【发布时间】:2016-06-04 13:09:02
【问题描述】:
我的 bash 脚本面临一些奇怪的行为。它基本上是一个脚本,如果它第一次失败,它会尝试多次 ping 远程主机。我这样做是为了排除任何虚假警报。我想我可以通过编写一个调用自身并再次尝试 ping 的递归函数来快速实现这一点。
我的问题是返回值。我发现该函数多次返回与递归次数相对应的返回值。这很奇怪。例如,在我下面的代码中,ip_up() 函数应该返回 1 表示远程主机启动,返回 0 表示关闭。但是,当远程主机关闭时,该函数返回 0 两次,这对应于所做的递归。
我的代码可能有什么问题,或者这就是 bash 的工作原理?
#!/bin/bash
ip_up(){
server_ip=$1
trials=$2
max_trials=2
status=0
echo "server ip is: $server_ip, trial $trials" >&2
if ping -i 1 -c 3 "$server_ip" &> /dev/null
then
status=1
else
status=0
while (( "$trials" < "$max_trials" )); do
echo -e "$server_ip is down: Trial $trials, checking again after 1 sec" >&2
sleep 1
((trials++))
ip_up "$server_ip" "$trials"
done
fi
echo "$status"
}
status=$(ip_up "$ip" 1)
echo -e "the returned status is: ====$status====\n"
if [ "$server_status" -eq 0 ]; then
msg="$timestamp: Server $hostname ($ip) is DOWN"; echo "$msg"
fi
<<'COMMENT'
//results
$ ./check_servers.sh
checking box1(173.36.232.6)
server ip is: 173.36.232.6, trial 1
173.36.232.6 is down: Trial 1, checking again after 1 sec
server ip is: 173.36.232.6, trial 2
the returned status is: ====0
0====
./check_servers.sh: line 41: [: 0
0: integer expression expected
Sat Jun 4 15:16:11 EAT 2016 box2 (173.36.232.7) is UP
checking box2 (173.36.232.7)
server ip is: 173.36.232.7, trial 1
the returned status is: ====1====
COMMENT
【问题讨论】:
-
这主要是关于递归一般如何工作的问题,因此 Bash 在实现递归时如何工作。对函数的每次递归调用最终都会返回;每次调用返回一个。如果您不想要递归和多次返回,请改用迭代。事实上,您的代码中已经有了迭代;它只是迭代地递归——这很奇怪。如果你有
if ping,你应该使用while循环,它可以测试迭代计数和ping 状态。整本书需要认真重写。 -
感谢@JonathanLeffler 的回答。这当然是有道理的,我已经根据你的建议写了一篇文章。为了学习bash中的递归,你将如何实现它?
-
恕我直言,我不会递归地实现代码——句号。好吧,除非它是用 LISP 编写的,否则我可能别无选择。学习递归定义的问题的递归。我将提供一个答案来展示我将如何编写该过程,但它不会涉及递归。如果您坚持需要递归,请找其他人帮忙。