linux - Bash:返回值不完整

标签 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 '`

最佳答案

您的代码实际上根本没有启动该函数; 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/

相关文章:

c - SIGINT 信号后进程终止

swift - 值替换后恢复字符串插值

bash - 根据字段值将一个 CSV 拆分为多个文件

bash - 如何逃脱历史扩展感叹号!在双引号字符串中?

php - 在 bash 中分解文件

regex - 查找/替换目录和 Bash 脚本

linux - 如何在 Arch linux 下使用 Gummiboot 从 Uefi 启动 Xen Hypervisor

c++ - mmap() 的 Linux 非持久性后备存储

c# - 如何用两个连续的空格分割一个字符串

java - 将小数点 1 到 10 替换为名称 ("one", "two"..)