Pipefail 阻止命令替换评估 pgrep?

Pipefail 阻止命令替换评估 pgrep?

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"

相关内容