首页 > 解决方案 > 当 var=$(... | grep "value") 为空时脚本退出并出错,但在 grep 有结果时有效

问题描述

我有以下 bash 代码(在 Red Hat 上运行),当我启用set -o errexit并且代码中的变量为空时退出,但在设置变量时工作正常;该代码旨在测试是否存在匹配的屏幕会话.monitor_*,如果存在则执行某些操作。

我开启了以下功能:

set -o errexit
set -x xtrace; PS4='$LINENO: '

如果存在与上述模式匹配的会话,则它可以工作;但是,如果没有匹配项,它只会退出,除了 xtrace 的以下输出之外没有任何信息

someuser:~/scripts/tests> ./if_test.sh
+ ./if_test.sh
+ PS4='$LINENO: '
4: set -o errexit
5: set -o pipefail
6: set -o nounset
88: /usr/bin/ls -lR /var/run/uscreens/S-storage-rsync
88: grep '.monitor_*'
88: awk '{ print $9 }'
88: /usr/bin/grep -Ev 'total|uscreens'
8: ms=

我测试了我用来设置msvar 的命令,它与 xtrace 输出一致,它没有设置。

someuser:~/scripts/tests> test -n "${mn}"
+ test -n ''

我曾尝试使用 select 语句并得到相同的结果......我无法弄清楚,有人能帮忙吗?谢谢。

我通读了所有可能的解决方案建议,似乎没有解决我的问题。

编码:

#!/usr/bin/env bash

set -o xtrace; PS4='$LINENO: '
set -o errexit
set -o pipefail
set -o nounset

ms="$(/usr/bin/ls -lR /var/run/uscreens/S-"${USER}" | /usr/bin/grep -Ev "total|uscreens" | grep ".monitor_*" | awk '{ print $9 }')"

if [[ -z "${ms}" ]]; then
    echo "Handling empty result"
elif [[ -n "${ms}" ]]; then
    echo "Handling non-empty result"
fi

提出了以下答案:Test if a variable is set in bash when using "set -o nounset" ; 但是,它根本没有解决问题。在我的情况下,正在测试的变量已设置,正如我在详细信息中所述,它设置为"",或者什么都没有。谢谢; 但是,它没有帮助。

它似乎真的是它不喜欢的变量声明。

ms="$(/usr/bin/ls -lR /var/run/uscreens/S-"${USER}" | /usr/bin/grep -Ev "total|uscreens" | grep ".monitor_*" | awk '{ print $9 }')"

标签: linuxbash

解决方案


  • 您正在运行set -o pipefail,因此如果管道中的任何组件具有非零退出状态,则整个管道将被视为具有非零退出状态。
  • 您的管道运行grepgrep只要没有找到匹配项,就具有非零状态。
  • 你正在跑步set -o errexit(又名set -e)。启用后,只要errexit任何命令失败,脚本就会终止(受到一系列冗长而复杂的异常的影响;其中一些在BashFAQ #105 的练习部分中介绍,而其他一些则在这个出色的参考中有所涉及)。

因此,当您的grep命令中没有匹配项时,您的脚本将在运行相关管道的命令替换时终止。


如果您想从 的行为中排除特定命令set -e,最简单的方法是简单地附加||:(的简写|| true),这会将命令标记为“已检查”。


推荐阅读