意图
我正在编写一个小 shell 脚本(POSIX,除了system_beep()
)。
该脚本在 Cygwin 中运行,应该找出我母亲的笔记本电脑是否关闭,并给出明确的结果,如果打开,还会发出 5 次蜂鸣声。
代码
#!/bin/bash
set -o nounset
blink=$(tput blink)
bold=$(tput bold)
reverse=$(tput rev)
no_color=$(tput sgr0)
red=$(tput setaf 1)
#blue=$(tput setaf 4)
#cyan=$(tput setaf 6)
green=$(tput setaf 2)
#white=$(tput setaf 7)
#yellow=$(tput setaf 3)
#magenta=$(tput setaf 5)
lid_open_color="${blink}${bold}${reverse}${red}"
lid_closed_color="${blink}${bold}${reverse}${green}"
system_beep()
{
echo -ne '\007'
}
beep_x_times()
{
i=1; while [ "$i" -le "$1" ]; do
i=$((i + 1))
system_beep
sleep 1s
done
}
get_lid_state_mom()
{
if ! ssh heruser@laptop_ip -p port_number -o ConnectTimeout=3 -i /home/myuser/.ssh/id_rsa 2> /dev/null \
cat /proc/acpi/button/lid/LID0/state | awk '{print $2}'; then
# if [ "$?" -ne 0 ]; then
echo "Error connecting to Mom via SSH"
exit 1
fi
}
state=$(get_lid_state_mom)
if [ "$state" = "closed" ]; then
echo "${lid_closed_color}closed${no_color}"
elif [ "$state" = "open" ]; then
echo "${lid_open_color}open${no_color}"
beep_x_times 5
else
echo "Some error occurred!"
fi
问题
尽管我很努力,但我似乎无法理解为什么我会得到:
$ ./lid-status-mama-beep
Some error occurred!
虽然它的行为正确,但当笔记本电脑可通过 SSH 连接时:
如果盖子关闭:
$ ./lid-status-mama-beep
closed
如果盖子打开:
$ ./lid-status-mama-beep
open
我显然在这个错误处理案例中做错了什么。
问题
如何使该脚本输出:
Error connecting to Mom via SSH
当连接因某种原因断开时?
答案1
解决方案
请参阅注释以获取每行的解释。
get_lid_state_mom()
{
# I have omitted awk completely here, getting raw value instead
ssh -p port_number -o ConnectTimeout=3 -i /home/myuser/.ssh/id_rsa heruser@laptop_ip cat /proc/acpi/button/lid/LID0/state 2> /dev/null
}
# this had to be renamed in order for me to know it is a raw value
lid_state_raw=$(get_lid_state_mom)
# indirect test for successful execution seems to be the best method
if [ "$?" -ne 0 ]; then
echo "Error connecting to Mom via SSH"
exit 1
fi
# after the success extract the state from the raw value
lid_state=$(echo "$lid_state_raw" | awk '{print $2}')
答案2
原因
你的 if 语句get_lid_state_mom
是错误的。
second_command
在下面的代码片段中,您可以看到仅考虑了的退出值。
if ! first_command | second_command ; then
echo "second_command exited false"
fi
反转!
all 的结果first_command | second_command
,因此相当于! second_command
在您的代码中, Second_command 是对 的调用awk
,因此if
仅当 awk 失败时您的值为 true 。