如何更改此代码以免发出错误,换句话说,xargs
如果 stdout 为空,则不执行代码。
终端:
$ cat << EOF > dummy.sh
#! /usr/bin/env bash
[[ -f "\$1" ]] && echo "file=\$1" || { echo "error"; exit 1; }
shift
(( \$# == 0 )) || "\$0" "\$@"
EOF
$ chmod +x dummy.sh
$ mkdir trash.later && touch trash.later/foo
$ find trash.later -type f | xargs -n 1 ./dummy.sh
file=trash.later/foo
$ find trash.later -type f | grep 'bar' | xargs -n 1 ./dummy.sh
error
不要
xargs
在find
.xargs
默认情况下,期望输入的参数以没有命令输出的格式分隔,当然不是find
. 的输出find -print
也不能可靠地进行后处理。find
使用xargs
可靠排序的唯一方法是使用-print0
和-0
非标准扩展(最初来自 GNUfind
/xargs
,但现在在许多其他实现中都可以找到)。如果输入为空,GNU
xargs
也有一个-r
/扩展名来不运行命令(某些实现,例如 NetBSD 上的默认实现)。--no-run-if-empty
xargs
所以在这里,使用 GNU
find
//xargs
或grep
兼容的,你可以这样做:但这与标准相比没有优势:
( where在文件路径中
-path '*bar*'
查找任何地方,就像您尝试做的那样。替换为仅在文件名中查找(其路径的最后一个组成部分))。bar
grep bar
-name '*bar*'
bar
在为什么循环查找的输出是不好的做法?
作为对您问题的更一般的回答,对于
xargs
不支持-r
/的实现,--no-run-if-empty
解决方法是使用sh
包装器。代替:
做:
sh
如果没有输入,它仍然会运行,但由于参数列表是空的,循环中不会有通过,所以cmd
不会运行。另请参阅仅在输入非空时运行命令的
ifne
命令moreutils
但是请注意,如果输入不为空但仅包含空行,
ifne
则将运行xargs
但xargs
仍会认为其输入没有参数并且仍然在cmd
没有参数的情况下运行一次(NetBSD 除外)。为了完整性
cmd
如果输入为空/空白,也不会运行。在这种情况下,将输入拆分为参数是不同的:前导空格被删除,引号仍然被处理(以xargs
自己独特的方式),但否则参数是整行而不是空格分隔的单词。