Bash 使用find | xargs重定向到包含替换值的输出文件

Bash 使用find | xargs重定向到包含替换值的输出文件,bash,Bash,我正在尝试在启动vagrant VM时将一个文件写入apache私有临时文件夹。路径如下所示: /tmp/systemd-private-c6d69c26cea64df2ab2980b337e60b79-apache2.service-b0KNWB/tmp 通过执行以下操作,我找到了在该变量路径上可靠执行命令的方法: find /tmp/ | grep -P "apache" | head -n 1 | xargs -I% touch %/tmp/aaa.txt 这很好用

我正在尝试在启动vagrant VM时将一个文件写入apache私有临时文件夹。路径如下所示:

/tmp/systemd-private-c6d69c26cea64df2ab2980b337e60b79-apache2.service-b0KNWB/tmp
通过执行以下操作,我找到了在该变量路径上可靠执行命令的方法:

find /tmp/ | grep -P "apache" | head -n 1 | xargs -I% touch %/tmp/aaa.txt
这很好用。如果我试图通过执行

find /tmp/ | grep -P "apache" | head -n 1 | xargs -I% echo "qweqwe" > %/tmp/aaa.txt
我只得到
-bash:%/tmp/aaa.txt:不是目录


echo
xargs
一起使用肯定有问题,但我真的被困在这里了。

考虑一些更类似于:

find /tmp \
  -iname '*apache*' \
  -type d \
  -exec sh -c 'for arg do echo "qweqwe" >"$arg/tmp/aaa.txt"; done' _ {} \;
  -quit  # stop after the first one
这样,您就可以将重定向放在传递给要运行的shell的代码中,这样就可以执行重定向。(如果您想有效地循环多个参数,只需取出
-quit
并将
{}\
更改为
{}+


此外,通过将文件名作为带外数据从代码中传递,可以避免安全问题。重定向到的简单解决方案可能使用
xargs-I%sh-c'…>%/tmp/aaa.txt“
,但这是危险的(就像任何其他将文字数据替换为代码的地方):可以创建文件名的人,如
/tmp/$(rm-rf~)”$(rm-rf~)“/evil/apache/
可能会导致您在运行此代码时删除主目录。

问题是shell在启动
xargs
之前执行重定向……因此
echo
没有问题,而
有问题<代码>>不是
echo
的一个参数,它是一种shell语法,无论运行什么命令,shell都将以相同的方式执行。也就是说,这似乎有点过分了<代码>用于d in/tmp/systemd private-*apache*/;继续;echo“qweqwe”>“$f/tmp/aaa.txt”;完成,您不需要
查找
grep
头部
xargs
。干杯,您在其他评论中的建议很好:
对于d in/tmp/systemd private-*apache*;继续;echo“qweqwe”>“$d/tmp/aaa.txt”;完成
。我知道我的方法可能有些过头了。