将从 xargs 传递到 bash 的参数保存为变量以进行处理
Saving arguments passed from xargs to bash as a variable for processing
我正在尝试 运行 并行执行许多命令,并且需要先对输入进行一些字符串操作。我怎样才能让下面的例子起作用?
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v={}; echo $v"
当我使用它时,$v
为空。为什么不保存为 {}
的值?
父 shell 扩展 $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"
顺便说一句,要亲自了解这确实是正在发生的事情,一种方法是在父级 shell 中为 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
...
使用 GNU Parallel 你会做:
find . -mindepth 1 -type d | parallel -P 20 'v={}; echo "$v"'
我正在尝试 运行 并行执行许多命令,并且需要先对输入进行一些字符串操作。我怎样才能让下面的例子起作用?
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v={}; echo $v"
当我使用它时,$v
为空。为什么不保存为 {}
的值?
父 shell 扩展 $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"
顺便说一句,要亲自了解这确实是正在发生的事情,一种方法是在父级 shell 中为 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
...
使用 GNU Parallel 你会做:
find . -mindepth 1 -type d | parallel -P 20 'v={}; echo "$v"'