Проблема с тайм-аутом Netcat

Почему для следующей команды netcat не истекает время ожидания, если попытка подключения занимает более 3 секунд (т.е. Когда порт не открыт)? Я предполагал, что флаг -w будет тем, что мне нужно. ОС OSX 10.9.

nc -v -z -w 3 127.0.0.1 5050

Предполагая, что это сработало, я планировал реализовать так (не уверен, что это сработает, всего bash noob)

nc -v -z -w 3 127.0.0.1 5050 |/dev/null && echo "Online" || echo "Offline"

Ответ 1

Вам нужно перенаправить на /dev/null, а не на него. Попробуйте следующее:

nc -v -z -w 3 127.0.0.1 5050 &> /dev/null && echo "Online" || echo "Offline"

На моей машине порт 5050 не открыт, и я получаю следующее:

$ nc -v -z -w 3 localhost 5050 &> /dev/null && echo "Online" || echo "Offline"
Offline

Ответ 2

В Debian есть старый отчет об ошибке (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=97583), который продолжает работать в Debian GNU/Linux 7.7 (wheezy).

Я нашел "решение" этого: установка OpenBSD версии NC:

apt-get install netcat-openbsd

Ответ 3

Nc: nc обычно уже установлен, однако в некоторых системах, таких как Mac OS X, команда зависает в недоступных системах. (см. обходной путь)

nc -v -z -w 3 127.0.0.1 22 &> /dev/null && echo "Online" || echo "Offline"

Временное решение для Mac OSX:

bash -c '(sleep 3; kill $$) & exec nc -z 127.0.0.1 22' &> /dev/null
echo $?
0
bash -c '(sleep 3; kill $$) & exec nc -z 1.2.3.4 22' &> /dev/null
echo $?
143

(примеры иллюстрируют подключение к порту 22 ssh через пример хорошего и плохого хоста, используйте $?, чтобы определить, достиг ли он хоста со временем ожидания 3 секунды)

Для пользователей Mac (в основном) и т.д. Вы можете использовать команду в скрипте следующим образом:

    # -- use NMAP, if not avail. go with nc --
    if command -v nmap | grep -iq nmap ; then
        nmap ${ip} -PN -p ${ssh_port} | grep -iq "open"
        res=$?
    elif command -v nc | grep -iq nc ; then
        # -- run command if fails to complete in 3 secs assume host unreachable --
        ( nc -z ${ip} ${ssh_port} ) & pid=$!
        ( sleep 3 && kill -HUP $pid ) 2>/dev/null & watcher=$!
        if wait $pid 2>/dev/null; then
            pkill -HUP -P $watcher
            wait $watcher
            # -- command finished (we have connection) --
            res=0
        else
            # -- command failed (no connection) --
            res=1
        fi
    else
        echo "Error: You must have NC or NMAP installed"
    fi

    if [[ ${res} -lt 1 ]] ;then
        success=1
        echo "testing  => $ip SUCCESS connection over port ${ssh_port}"
        break;
    else
        echo "testing => $ip FAILED connection over port ${ssh_port}"
    fi