我正在尝试创建一个 bash 函数,以便我可以从代码的各个部分调用它。
#!/bin/bash
host='10.9.8.14'
if [ -z $host ]; then
echo "Usage: `basename $0` [HOST]"
exit 1
fi
ping_func () {
results=`ping -W 1 -c 1 $host | grep 'bytes from '`
return results
}
while :; do
result=ping_func
# result=`ping -W 1 -c 1 $host | grep 'bytes from '`
if [ $? -gt 0 ]; then
echo -e "`date +'%Y/%m/%d %H:%M:%S'` - host $host is \033[0;31mdown\033[0m"
for i in `seq 1 10`;
do
echo $i
done
if [ $i -eq 10 ]; then
service openvpn restart > /dev/null 2>&1
sleep 5
fi
else
echo -e "`date +'%Y/%m/%d %H:%M:%S'` - host $host is \033[0;32mok\033[0m -`echo $result | cut -d ':' -f 2`"
sleep 1 # avoid ping rain
fi
done
但是当我从循环内调用函数 ping_func 时,我的输出如下:
2019/06/29 08:15:38 - host 10.9.8.14 is ok -
2019/06/29 08:15:40 - host 10.9.8.14 is ok -
2019/06/29 08:15:42 - host 10.9.8.14 is ok -
2019/06/29 08:15:44 - host 10.9.8.14 is ok -
2019/06/29 08:15:46 - host 10.9.8.14 is ok -
2019/06/29 08:15:48 - host 10.9.8.14 is ok -
2019/06/29 08:15:50 - host 10.9.8.14 is ok -
没有该函数,但在每个循环周期调用 ping,我得到了正确的输出。
2019/06/29 08:15:26 - host 10.9.8.14 is ok - icmp_seq=1 ttl=64 time=414 ms
2019/06/29 08:15:27 - host 10.9.8.14 is ok - icmp_seq=1 ttl=64 time=407 ms
2019/06/29 08:15:29 - host 10.9.8.14 is ok - icmp_seq=1 ttl=64 time=410 ms
2019/06/29 08:15:30 - host 10.9.8.14 is ok - icmp_seq=1 ttl=64 time=412 ms
2019/06/29 08:15:31 - host 10.9.8.14 is ok - icmp_seq=1 ttl=64 time=358 ms
2019/06/29 08:15:33 - host 10.9.8.14 is ok - icmp_seq=1 ttl=64 time=466 ms
2019/06/29 08:15:34 - host 10.9.8.14 is ok - icmp_seq=1 ttl=64 time=407 ms
如何调用 bash 函数并返回所有字符串数据输出?
有问题的代码行:
result=ping_func
result=`ping -W 1 -c 1 $host | grep 'bytes from '`
最佳答案
您的代码实际上根本没有启动该函数; result=ping_func
并不是将运行 ping_func
的输出分配给 result
的方式(即使是这样,return
也不是从函数中发出某些内容作为输出的方式)。
#!/usr/bin/env bash
host=${1:-10.9.8.14}
# a regular expression to pull out the line we want; tune to taste
# this is internal to bash, so much faster than calling grep/sed/cut/etc once
# for each line!
content_re='[Ff]rom.*:[[:space:]]+([[:print:]]*)'
ping_func() {
local output retval # declare your locals so we don't leak scope
# actually call ping; store its output and success/failure state separately
output=$(ping -W 1 -c 1 "$1"); retval=$?
# compare against content_re as a regex; far faster than grep
[[ $output =~ $content_re ]] && printf '%s\n' "${BASH_REMATCH[1]}"
# return the exit status we stored earlier as our own
return "$retval"
}
while :; do
# the if branches on whether the returned retval was 0
# ...whereas the stdout written by printf is put in result
if result=$(ping_func "$host"); then
# using printf %(...)T needs a new bash, but is *far* faster than date
printf '%(%Y%m%d %H:%M:%S)T Host is UP: %s\n' -1 "$result"
else
printf '%(%Y%m%d %H:%M:%S)T Host is DOWN: %s\n' -1 "$result"
fi
sleep 1
done
也就是说,我自己永远不会编写这样的代码:最好运行一个长时间运行的 ping
副本并单独处理它写入的每一行输出,这样您就不会一遍又一遍地启动 ping。请参阅BashFAQ #1寻求指导。
关于linux - Bash:返回值不完整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56817929/