Linux if elif else 失败

Linux if elif else 失败

我正在尝试查找挂载点 1 是否可用,如果不可用,则挂载它。如果挂载点 1 失败,则挂载第二个。如果失败,则显示失败消息。

以下是代码:

mount > /tmp/log;
if grep -ohw 123.456.789 /tmp/log >/dev/null; then echo -e " STACK MOUNT \e[1;33mALREADY\e[00m AVAILABLE \e[1;33mPASSED\e[00m ";
elif mount -t nfs -o ro,nolock 123.456.789:/opt/media/ /mount/stack &>/dev/null; then mount > /tmp/log;
if grep -ohw 123.456.789 /tmp/log >/dev/null; then echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m ";
elif mount -t nfs -o ro,nolock 223.456.789:/opt/media/ /mount/stack &>/dev/null; then mount > /tmp/log;
if grep -ohw 223.456.789 /tmp/log >/dev/null; then echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m ";
else echo -e " STACK MOUNT NOT AVAILABLE          \e[00;31mFAILED\e[00m"; fi; fi; fi | tee -a /tmp/log

如果 2 个挂载点中的任何一个都挂载了,结果就很好。问题是,当没有挂载任何挂载点时,不会显示 FAILURE 语句。

答案1

失败消息未显示,因为该语句嵌套在太多“then”子句中。我建议简化逻辑如下:

is_mounted() {
    mount | grep -qohw "$1
}


{
pass=
for ip in  123.456.789  223.456.789
do
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT \e[1;33mALREADY\e[00m AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
    mount -t nfs -o ro,nolock "$ip:/opt/media/" /mount/stack &>/dev/null
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
done
[ "$pass" ] || echo -e " STACK MOUNT NOT AVAILABLE          \e[00;31mFAILED\e[00m"
} | tee /tmp/log
mount >>/tmp/log

在您的原始代码中,/tmp/log正在被 更新,tee -a同时它被 开始覆盖mount。这可能不可靠。上面的代码避免了这种情况。

PS如何调试: 如果代码“挂起”,可能是因为mount在尝试 NFS 挂载时挂起。要确定原因,请 (a) 添加一些诊断echo语句,(b) 显示mount输出(如果有)(它已在上面的代码中处理掉),以及 (c) 添加选项-vmount使其详细。也可以删除该tee语句,这样就不会出现输出缓冲问题。因此,请尝试:

is_mounted() {
    mount | grep -qohw "$1
}

{
pass=
echo "Starting to loop over IP addresses"
for ip in  139.41.170.10 197.21.82.10 139.41.170.11 197.21.82.11 139.31.125.11
do
    echo "Testing to see if $ip is mounted"
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT \e[1;33mALREADY\e[00m AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
    echo "Attempting to mount $ip"
    mount -v -t nfs -o ro,nolock "$ip:/opt/media/" /mount/stack
    echo "mount finished with exit code=$?"
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
    echo "Not able to mount $ip"
done
echo "Completed loop over IP addresses with pass=$pass"
[ "$pass" ] || echo -e " STACK MOUNT NOT AVAILABLE          \e[00;31mFAILED\e[00m"
}
mount >>/tmp/log

PPS 处理宕机的主机: 处理 NFS 挂载时,该mount命令通常具有非常长的 timeout.on hosts(在我的系统上超过 2 分钟)。相比之下,ping可以在几秒钟内检测主机是否已关闭。因此,为了避免长时间超时mount,可以先使用 测试主机是否已启动ping。为此,请将以下mount -t nfs...行替换为:

ping -c2 "$ip" >/dev/null && mount -t nfs -o ro,nolock "$ip:/opt/media/" /mount/stack &>/dev/null

当然,这假设您处于允许主机响应 ping 的网络上。

答案2

这归结于“fi”的放置。如果你更正式地布局你的脚本,它会变得更加明显 - 第一个“if”/“elif”块直到第三个“fi”才完成。从你对需求的描述来看,我期望“if/elif/fi、if/elif/fi、if/else/fi”。

正如 Slartibartfast 指出的那样,将其重组为单个 if/elif/elif.../else/fi 链可能更具可读性/可维护性,但是正如您构建它时那样,您可以通过移动后面的“fi”并保持其余部分不变来修复它。

当前代码,格式如下:

安装 > /tmp/log;
如果 grep -ohw 123.456.789 /tmp/log > /dev/null;
然后
    echo -e " 堆栈挂载 \e[1;33m已经\e[00m 可用 \e[1;33m已通过\e[00m ";
elif mount -t nfs -o ro,nolock 123.456.789:/opt/media/ /mount/stack &>/dev/null;
然后
    安装 > /tmp/log;
    如果 grep -ohw 123.456.789 /tmp/log > /dev/null;
    然后
        echo -e " 堆栈挂载可用 \e[1;33mPASSED\e[00m ";
    elif mount -t nfs -o ro,nolock 223.456.789:/opt/media/ /mount/stack &>/dev/null;
    然后
        安装 > /tmp/log;
        如果 grep -ohw 223.456.789 /tmp/log > /dev/null;
        然后
            echo -e " 堆栈挂载可用 \e[1;33mPASSED\e[00m ";
        别的
            echo -e " 堆栈安装不可用 \e[00;31mFAILED\e[00m";
        科幻;
    科幻;
fi | tee -a /tmp/log

如图所示,如果原始挂载不存在,并且第一个挂载命令失败,那么我们将退出整个“if”块 - 后面的任何代码都不可能运行。

答案3

有太多如果。

if A; then B
elif C; then D
elif E; then F
else G
fi

希望有所帮助。

此外,对于需要按顺序完成的任务,为确保所有任务都成功完成,您可以尝试使用 && 连接任务。这将导致按顺序执行的命令仅在其中一个失败时停止,并返回最后一个命令运行的退出代码:

mount squiggle && mount > /tmp/log && grep squiggle >/dev/null && echo -e "squiggle";

如果不成功,上述命令将尝试mount squiggle退出并显示错误/失败。如果成功,它将运行 mount 命令,输出到 /tmp/log。如果该命令失败,它将退出并显示错误。否则,将运行 grep 命令...

相关内容