Shell 防止POSIX xargs尝试运行空命令
我对bash不是很在行,但我正在尝试创建一个脚本来杀死一些java进程:Shell 防止POSIX xargs尝试运行空命令,shell,posix,kill,xargs,Shell,Posix,Kill,Xargs,我对bash不是很在行,但我正在尝试创建一个脚本来杀死一些java进程: /usr/ucb/ps -auxww \ | grep 'XUnit' \ | grep -v 'grep' \ | cut -c -2000 \ | awk '{print $2;}' \ | xargs kill 此处使用的是cut,因为awk可能会因线路过长而失效(请参阅中的LINE\u MAXlimit) 当没有此类进程时会出现问题-xargs尝试在没有参数的情
/usr/ucb/ps -auxww \
| grep 'XUnit' \
| grep -v 'grep' \
| cut -c -2000 \
| awk '{print $2;}' \
| xargs kill
此处使用的是cut
,因为awk
可能会因线路过长而失效(请参阅中的LINE\u MAX
limit)
当没有此类进程时会出现问题-xargs
尝试在没有参数的情况下运行kill
,导致错误
我的xargs不接受
-r
或-如果args为空则不运行,正如回答中所建议的那样。专门解决手头的问题,忽略手头的方法实际上是否是终止进程的适当方法:
xargs sh -c '[ $# -gt 0 ] && exec "$0" "$@"' kill
这种方法让xargs
启动一个shell,该shell查看其参数列表的长度(如果只传递kill
,则该长度将为0,因为-c'script'
后面的参数以$0
开头,不包括在$\code>计数中);只有在至少给出一个参数的情况下,该shell才会运行给定的命令。是通常情况下,有-r
选项来xargs
,请参阅:
否则,您可以创建一个bash函数并将其放在xargs之前的管道中:
handle_empty(){
while read line; do
if test -z "$line"; then
echo 'There was an empty line, exiting.' > /dev/stderr
exit 0;
fi
echo "$line"
done;
}
export -f handle_empty;
并像这样使用它:
docker volume ls -qf dangling=true | handle_empty | xargs docker volume rm
有关更多信息,请参阅:
这里已经给出了答案:顺便说一句——如果你有pkill
,你最好在一个命令中使用它,而不是试图通过一个巨大的管道过滤ps
输出。而且,awk
可以自己完成grep
和cut
的工作,所以即使你要坚持使用管道,也没有理由让它如此复杂。例如:ps auxww | awk'(/XUnit/&&!/awk/){print$2}'
。但是,如上所述,最佳实践是根本不使用ps
。阅读POSIX规范中关于awk
,允许其符合LINE_MAX
,通常为2k。刚刚在那里学到了一些新的东西——尽管我很好奇,您正在使用的哪个实现实际上强制了这个限制。@BenjaminW.,是的!我认为非常节省的方法是ps-e-opid=-oargs=|awk'/[X]Unit/{print$1}'
。如果您担心这个限制,可以在awk之前抛出一个cut-c-$(getconf LINE\u MAX)
。为什么不在管道中放置一个handle\u empty
函数呢?如果参数为空,则使用0退出并回显“有一个空行”。。。请参阅:或使用-r选项--r
不可移植--正如您链接的答案所示。导出的函数也不能移植到非bash shell。OP非常清楚,问题是专门要求一个能在POSIX基线平台上工作的解决方案(而且我们已经有很多几乎重复的解决方案没有这一要求)。FWIW,我觉得POSIX xargs这样做绝对是可笑的,甚至是危险的。@TorstenBronger,…老实说,缺少一些
-r
等效物可能是POSIXxargs设计缺陷中危险最小的;与类似于shell(但与shell不完全兼容)的输入解析或允许实现执行子字符串扩展(从而鼓励xargs-I{}sh-c'{}…'
使用模式,并伴随shell注入风险)相比,它的安全性要低得多.从问题的最后一行开始:我的xargs不接受-r
或-如果参数为空则不运行,正如在对未指定POSIX合规性的相关问题的回答中所建议的那样。类似地,当他们指定严格的POSIX合规性时,导出的函数也被淘汰了。我不确定handle\u empty
是否真的符合您的要求。管道的所有部分同时运行--handle_empty
函数退出并不意味着xargs
不运行(或阻止xargs
在没有输入的情况下被调用;因此,如果根本没有输入,则从一开始就不会进入while read
循环),它只是确保xargs看不到输入中超过第一个空行的任何内容。