Bash oneliner with pipes and if condition condition error

时间:2017-10-15 17:49:17

标签: linux bash shell if-statement pipe

我试图使用if condition as

来查找bash中特定进程的编号
if ps auwx | grep -v grep | grep -ic python -le 2; then echo error; else echo no_error; fi

我的输出为

grep: python: No such file or directory

NO_ERROR

如果我使用管道,单线程似乎会中断,如果我省略管道则不会引发错误,如果我使用绝对路径grep也没关系。如果没有管道,我就无法获得所需的结果管道。我在这做错了什么?我可以在脚本文件中完成此操作,将其分解为变量然后进行比较,但我将此作为练习来学习bash。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:4)

首先,if命令的语法是:

if cmd; then
    # cmd exited with status 0 (success)
else
    # cmd exited with status >0 (fail)
fi

上面的cmd是所谓的列表 - 一系列管道。每个管道都是一系列用|分隔的命令。

-le运算符仅由test命令(也称为[[[)解释为 ,而不是if运算符{1}}命令。

所以,当你说:

if ps auwx | grep -v grep | grep -ic python -le 2; then ... fi

你实际用参数调用grep

grep -ic python -le 2

由于-e用于指定搜索模式,因此参数python被解释为搜索模式2的文件的文件名。这就是grep告诉您无法找到名为python的文件的原因。

要在if中测试命令管道的输出,您可以在[[ / [ / test内使用命令替换(如另一个答案所示) :

if [[ $(ps auwx | grep -v grep | grep -ic python) -le 2 ]]; then ... fi

或在(( .. ))内,使用隐式算术比较:

if (( $(ps auwx | grep -v grep | grep -ic python) <= 2 )); then ... fi

答案 1 :(得分:2)

在条件

中使用命令替换
if [[ $(ps ...) -le 2 ]]; then