我正在尝试并行运行许多命令,并且需要先对输入进行一些字符串操作。我怎样才能让下面的例子工作?
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v={}; echo $v"
当我使用它时,$v
为空。为什么不将其保存为 {}
的值?
最佳答案
父外壳正在扩展$v
在 字符串被传递给xargs
之前.
假设您的 find
命令找到一个名为 ./stuff
的子目录.
一、父bash
shell(你输入 find
命令的那个)将展开 $v
, 因为字符串在双引号中。您目前没有为变量 v
设置值, 因此它扩展为一个空字符串。
接下来,参数被传递给 xargs
,它会看到这个:v={}; echo
然后,xargs
将阅读 ./stuff
从管道中,替换 {}
与 ./stuff
最后,sh
命令由 xargs
执行, 和 sh
会看到这个:v=./stuff; echo
要解决此问题,您需要转义 $
这样父 shell 就不会扩展它,或者使用单引号来避免变量扩展。您可能还应该引用这些字符串,以便其中包含空格的任何目录名称都不会导致最终的 sh
出现问题。命令:
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v=\"{}\"; echo \"\$v\""
或
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c 'v="{}"; echo "$v"'
使用任一命令,最终的 sh
进程将看到:v="./stuff"; echo "$v"
顺便说一句,要亲自了解这确实是正在发生的事情,一种方法是为 v
设置一个值。在父 shell 中,然后运行您的原始命令。外壳将展开 $v
为您设置的任何值,您将看到 find
找到的每个目录都重复该值.
$ v=foobar
$ find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v={}; echo $v"
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
...
关于bash - 将从 xargs 传递到 bash 的参数保存为变量以进行处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36186394/