xargs 忽略 && 之后的部分命令



我打算获得一个逗号分隔的文件列表,然后将其作为参数传递给使用xargs的命令。

然而,xargs似乎忽略了命令在&。

$ find */build* -printf '%h/%f,'
jenkins/build.jenkinsfile,jenkins/build-x.groovy,

$ find */build* -printf '%h/%f,' | xargs -t python3 -m coverage combine python-bridge && python3 -m coverage xml --omit
python3 -m coverage combine python-bridge jenkins/build.jenkinsfile,jenkins/build-x.groovy,
Couldn't combine from non-existent path 'jenkins/build.jenkinsfile,jenkins/build-x.groovy,'

因此,该命令被解释为:

python3 -m coverage combine python-bridge jenkins/build.jenkinsfile,jenkins/build-x.groovy,

预期:

python3 -m coverage combine python-bridge && python3 -m coverage xml --omit jenkins/build.jenkinsfile,jenkins/build-x.groovy,

任何指针都会有很大帮助。

Meta:我写了一条更长的评论,Stack似乎以某种方式丢弃了它,所以我正在重新做这件事,以获得编辑历史记录,尽管我不确定这真的是在编程(因此可能需要删除)。

这不是xargsshell将输入分解为两个命令,然后将find */build* -printf '%h/%f,'作为一个进程运行,stdout连接到管道,将xargs -t python3 -m coverage combine python-bridge作为另一个进程,stdin连接到同一管道,从而执行第一个管道;只有在这两个过程都完成之后,并且只有在xargs成功的情况下(这反过来也是只有python3 -m ...成功的情况),shell才会运行第二个命令python3 -m coverage xml --omit作为第三个进程。

您可以通过引用'&&' "&&" &&中的任何一个来将&&传递给xargs。但是,xargs不是shell,并且不会将&&解释为"and"运算符;它将运行一个python3进程,带有参数-m coverage combine python-bridge && python3 -m coverage xml --omit,并附加(一个)输入'filename]jenkins/build.jenkinsfile,jenkins/build-x.groovy,,但这也不起作用。

可以xargs运行一个shell,该shell依次运行您想要的命令:

find */build* -printf '%h/%f,' | 
xargs -t sh -c 'python3 -m coverage combine python-bridge && python3 -m coverage xml --omit $*' dummy0'
# in general you should use "$@" to prevent split+glob from mangling 'special' arguments
# but here they have already survived xargs default parsing so shouldn't be special

但更简单的是更恰当地安排命令:

python3 -m coverage combine python-bridge && 
find */build* -printf '%h/%f,' | python3 -m coverage xml --omit

或者,因为只有当文件列表适合一个命令时,这才能正常工作,所以你实际上不想要xargs的主要功能,只需要

python3 -m coverage combine python-bridge && 
python3 -m coverage xml --omit $(find */build* -printf '%h/%f,')

最新更新