bash - 将从 xargs 传递到 bash 的参数保存为变量以进行处理

标签 bash xargs

我正在尝试并行运行许多命令,并且需要先对输入进行一些字符串操作。我怎样才能让下面的例子工作?

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/

相关文章:

bash - xargs -0 后如何执行多个命令?

Git 无法识别别名

linux - bash 如何用于将标准输出通过管道传输到脚本并写入终端?

c - Shell 脚本 vs C 性能

bash - 无法使用 coproc 命令和进程列表在 bash 中创建超出子 shell 的嵌套 shell

linux - xargs 不适用于 replstr(替换字符串)

command-line - xargs 不识别 bash 别名

linux - 从文件名获取版本

使用 xargs 后 curl header

linux - 如何从具有并发控制的文件中执行一堆命令?