重击:返回值不完整

时间:2019-06-29 13:29:37

标签: linux string bash shell ping

我试图创建一个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 '`

1 个答案:

答案 0 :(得分:0)

您的代码实际上根本没有启动该功能。 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以获取指导。