我正在尝试查找挂载点 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) 添加选项-v
以mount
使其详细。也可以删除该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 命令...