【问题标题】:how do i reduce timeout on unix telnet on connection如何减少 unix telnet 连接超时
【发布时间】:2010-11-10 19:27:44
【问题描述】:

我有一个 unix shell 脚本,可以测试文件中列出的多个主机的 ftp 端口。

for i in `cat ftp-hosts.txt`
        do
        echo "QUIT" | telnet $i 21
done

一般来说,这个脚本可以工作,但是如果我遇到一个没有连接的主机,即 telnet 是“正在尝试...”,我怎样才能减少这个等待时间以便它可以测试下一个主机?

【问题讨论】:

    标签: telnet


    【解决方案1】:

    您是否尝试过使用 netcat (nc) 代替 telnet?它具有更大的灵活性,包括能够设置超时:

    echo 'QUIT' | nc -w SECONDS YOUR_HOST PORT
    # e.g.
    echo "QUIT" | nc -w 5       localhost 21
    

    -w 5 选项将在 5 秒后使连接超时。

    【讨论】:

    • 这个想法有效..我需要以这种方式使用它“nc -z -w 3 ip port”。但是对于没有连接的主机,它不会生成退出代码。
    • 奇怪。当我尝试-w 1 时,它只是挂在那里超过 1 秒...
    • @Michael 还有 -G 选项用于指定 TCP 连接超时
    • 漂亮!这让我在 postgres-check 解决方案中从 telnet 切换到nc stackoverflow.com/a/59657648/248616
    【解决方案2】:

    尝试使用 timeout3 脚本非常健壮,我在不同情况下使用了很多没有问题。 示例仅等待 3 秒以尝试检查 ssh 端口是否打开。

    > echo QUIT > quit.txt
    > ./timeout3 -t 3 telnet HOST 22 < quit.txt 
    

    输出:您可以使用 grep 搜索“已连接”或“已终止”

    timeout3 文件内容:

    #
    #!/bin/bash
    #
    # The Bash shell script executes a command with a time-out.
    # Upon time-out expiration SIGTERM (15) is sent to the process. If the signal
    # is blocked, then the subsequent SIGKILL (9) terminates it.
    #
    # Based on the Bash documentation example.
    # If you find it suitable, feel free to include
    # anywhere: the very same logic as in the original examples/scripts, a
    # little more transparent implementation to my taste.
    #
    # Dmitry V Golovashkin <Dmitry.Golovashkin@sas.com>
    
    scriptName="${0##*/}"
    declare -i DEFAULT_TIMEOUT=9
    declare -i DEFAULT_INTERVAL=1
    declare -i DEFAULT_DELAY=1
    # Timeout.
    declare -i timeout=DEFAULT_TIMEOUT
    
    # Interval between checks if the process is still alive.
    declare -i interval=DEFAULT_INTERVAL
    
    # Delay between posting the SIGTERM signal and destroying the process by SIGKILL.
    declare -i delay=DEFAULT_DELAY
    
    function printUsage() {
        cat <<EOF
    
    Synopsis
        $scriptName [-t timeout] [-i interval] [-d delay] command
        Execute a command with a time-out.
        Upon time-out expiration SIGTERM (15) is sent to the process. If SIGTERM
        signal is blocked, then the subsequent SIGKILL (9) terminates it.
    
        -t timeout
            Number of seconds to wait for command completion.
            Default value: $DEFAULT_TIMEOUT seconds.
    
        -i interval
            Interval between checks if the process is still alive.
            Positive integer, default value: $DEFAULT_INTERVAL seconds.
    
        -d delay
            Delay between posting the SIGTERM signal and destroying the
            process by SIGKILL. Default value: $DEFAULT_DELAY seconds.
    
    As of today, Bash does not support floating point arithmetic (sleep does),
    therefore all delay/time values must be integers.
    EOF
    }
    
    # Options.
    while getopts ":t:i:d:" option; do  
        case "$option" in
            t) timeout=$OPTARG ;;
            i) interval=$OPTARG ;;
            d) delay=$OPTARG ;;
            *) printUsage; exit 1 ;;
        esac
    done
    shift $((OPTIND - 1))
    
    # $# should be at least 1 (the command to execute), however it may be strictly
    # greater than 1 if the command itself has options.
    
    if (($# == 0 || interval <= 0)); then 
        printUsage
        exit 1
    fi
    
    # kill -0 pid   Exit code indicates if a signal may be sent to $pid process.
    (
        ((t = timeout))
    
        while ((t > 0)); do
            sleep $interval
            kill -0 $$ || exit 0
            ((t -= interval))
        done
        # Be nice, post SIGTERM first.
        # The 'exit 0' below will be executed if any preceeding command fails.
        kill -s SIGTERM $$ && kill -0 $$ || exit 0
        sleep $delay
        kill -s SIGKILL $$
    ) 2> /dev/null &
    
    exec "$@"
    
    #

    【讨论】:

      【解决方案3】:

      使用启动进程来休眠并终止 telnet 进程。大致:

      echo QUIT >quit.txt
      telnet $i 21 < quit.txt &
      sleep 10 && kill -9 %1 &
      ex=wait %1
      kill %2
      # Now check $ex for exit status of telnet.  Note: 127 inidicates success as the
      # telnet process completed before we got to the wait.
      

      我避免了回声 QUIT | telnet 管道在第一个作业的退出代码方面没有歧义。

      此代码未经测试。

      【讨论】:

      • telnet 在后台运行,命令序列也会在 10 秒内杀死它。 'ex=wait %1' 获取 telnet 的退出代码。如果 telnet 在超时之前完成,kill %2 将摆脱它。但是如果超时发生, kill %2 什么都不做。
      【解决方案4】:

      如果你有 nmap

       nmap -iL hostfile -p21  | awk '/Interesting/{ip=$NF}/ftp/&&/open/{print "ftp port opened for: "ip}'
      

      【讨论】:

      • 我的版本:nmap -PS -p "$port" --host-timeout 1501ms "$host" 2&gt;/dev/null | grep '/tcp *open '$? 将是 0 表示成功,1 表示关闭/超时。 1501ms 是最小超时时间。
      【解决方案5】:

      使用 timeout 以在 x 秒内退出,无论操作成功还是失败:

      timeout 运行一个有时间限制的命令,启动 COMMAND,然后杀死它 如果 DURATION 后仍在运行。

      公式:

      timeout <seconds> <operation>
      

      示例:

      timeout 5 ping google.com
      

      你的例子:

      for i in `cat ftp-hosts.txt`
      do
          timeout 5 telnet $i 21
      done
      

      【讨论】:

        猜你喜欢
        • 2013-08-25
        • 2017-09-08
        • 1970-01-01
        • 2018-08-31
        • 1970-01-01
        • 2013-02-09
        • 1970-01-01
        • 2018-06-19
        • 1970-01-01
        相关资源
        最近更新 更多