2009-07-14 11 views
18

Mam skrypt powłoki unix, który testuje porty ftp wielu hostów wymienionych w pliku.jak zmniejszyć timeout na unixie telnet na połączeniu

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

W ogóle ten skrypt działa, jednak jeśli wystąpi gospodarz, który nie łączyć, tj telnet jest „Próba ...”, w jaki sposób można skrócić ten czas oczekiwania więc może testować kolejny gospodarz?

Odpowiedz

28

Czy próbowałeś używać netcata (nc) zamiast telnetu? Ma większą elastyczność, łącznie mogąc ustawić timeout:

echo "QUIT" | nc -w 5 host 21 

Opcja -w 5 będzie limitu czasu połączenia po 5 sekundach.

+0

ten pomysł działa .. będzie trzeba użyć w ten sposób "nc -z -w 3 ip port". Jednak dla hostów, które nie łączą się, nie generuje kodu wyjścia. – chrisc

+0

dziwne. kiedy próbuję '-w 1' po prostu siedzi tam przez ponad 1 sekundę ... – Michael

+0

@Michael Istnieje również opcja' -G' dla określenia czasu oczekiwania na połączenie TCP –

1

Skorzystaj z procesu, aby uśpić i zabić proces telnetu. Z grubsza:

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. 

Unikałem echa QUIT | telnet pipeline nie pozostawia żadnych wątpliwości co do kodu wyjścia pierwszego zadania.

Ten kod nie został przetestowany.

+0

Czy możesz wyjaśnić kod, proszę? – ADTC

+0

Telnet działa w tle, podobnie jak sekwencja poleceń, która zabije ją w 10 sekund. "Ex = wait% 1" otrzymuje kod zakończenia telnetu. Jeśli telnet kończy się przed upływem limitu czasu, kill% 2 pozbywa się go. Ale jeśli dojdzie do przekroczenia limitu czasu, kill% 2 nic nie robi. –

1

jeśli masz nmap

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

Moja wersja tego: 'nmap -PS -p" $ port "--host-timeout 1501ms" $ host "2>/dev/null | grep '/ tcp * open' '. '$?' będzie 0 dla sukcesu, 1 dla zamkniętego/timeout. '1501ms' to minimalny limit czasu. – dwurf

3

Spróbuj użyć skryptu timeout3 jest bardzo wytrzymałe i użyłem sporo bez problemów w różnych sytuacjach. Przykład, aby odczekać 3 sekundy, aby sprawdzić, czy port ssh jest otwarty.

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

wyjścia: można grep dla "Connected" lub "zakończony"

zawartość pliku 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 <[email protected]> 

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 "[email protected]" 
#
Powiązane problemy