pgrep lftp -c
我的目标是在脚本中运行命令shell
来检查是否lftp
已经在运行。
但以下脚本永远不会超出“测试”输出。只有当我pipefail
完全删除该行时,脚本才会运行。为什么?
#!/usr/bin/env bash
set -e pipefail
echo test
EXISTING="$(pgrep lftp -c)"
echo $EXISTING
答案1
首先,关于 shell 脚本最佳实践指南的说明:避免对自己的变量名使用大写字母,因为这可能会导致与全局环境变量的命名冲突。举一个明显的例子,如果您命名一个变量PATH
,这将覆盖全局PATH
变量,这意味着将不再在预期位置找到可执行文件。
现在,在您向我们展示的脚本中,没有问题。它完全按照预期工作:您正在使用set -e
这意味着“如果任何命令失败则退出”,如果任何命令返回非 0 退出状态。如果pgrep
没有找到任何内容,它将以非 0 状态退出,因此您的脚本就在那里结束。
如果您手动尝试,您可以看到它的实际效果:
$ pgrep lftp -c
0
$ echo $?
1
为了避免这种情况,您可以使用wc
代替pgrep -c
,因为wc
如果行计数为 0,则不会以非 0 状态退出:
#!/usr/bin/env bash
set -e
echo test
existing="$(pgrep lftp | wc -l)"
echo "Found $existing instances of lftp"
lftp
当没有进程运行时,这会产生以下输出:
$ foo.sh
test
Found 0 instances of lftp
如果你想设置 bash 的pipefail
选项,你需要set -o pipefail
,而不是set -e
。所以也许你真正想要的是:
#!/usr/bin/env bash
set -o pipefail
echo test
existing="$(pgrep -c lftp)"
echo "Found $existing instances of lftp"