我想检测 Solaris 中的在线网络/shell 服务。我为此目的编写了以下脚本:
compare_ser()
{
if [ "$1" != "" ]; then
echo "True" >> Solaris.txt
fi
}
export -f compare_ser
svcs network/shell | cut -d ' ' -f1 | grep "online" | xargs -n1 bash -c 'compare_ser $@'
当我svcs network/shell | cut -d ' ' -f1 | grep "online" | xargs -n1 echo
在终端中运行时,我得到以下输出:
online
online
但我的脚本没有显示任何内容。它的问题是什么?
答案1
我相信,有一个更短的方法:
svcs network/shell | awk '/online/ {system("bash -c \"compare_ser "$1"\"")}'
亲爱的反对者,您能解释一下您的决定吗?你了解Linux到底是什么吗?上面的脚本是一个工作片段,也许有数百万种方法可以做到这一点。所以我要求一个解释。
答案2
用这个:
svcs network/shell | cut -d' ' -f1 | grep "online" | xargs -n1 -I{} bash -c 'compare_ser {}'
对{}
通过 生成的每个值进行插值xargs
。您$@
尝试插入命令行参数 - 但实际上没有。
答案3
您可能必须对字符串使用双引号来解析位置参数。
svcs network/shell | cut -d ' ' -f1 | grep "online" | xargs -n1 bash -c "compare_ser $@"
答案4
svcs network/shell | sed -n '/^online /c\
True' >> Solaris.txt
……应该差不多。
这原因不过,您的脚本没有显示任何内容,因为 shell 函数是 shell 代码,必须由已经知道它的 shell 执行 - 该函数必须首先在运行它的 shell 中声明才能工作。
然而,当您调用 时xargs
,您调用的程序又调用另一个程序,当然,该程序是一个 shell,但是xargs
调用您的新 shell 进程是不是了解当前 shell 中定义的 shell 函数。
当然,export -f
如果您的 shell 理解这意味着什么,您可能会这样做,但如果您在 Solaris 系统上使用ksh
- 那么它就不会。无论如何,这将是一个可怕如果确实实现了目标,那么实现目标的效率很低。