Избавьтесь от ошибки «соединение отказано» в сценарии bash

Вы не можете пинговать manpage! Что делает ping?

NAME
       ping, ping6 - send ICMP ECHO_REQUEST to network hosts


Некоторые ссылки для дальнейшего чтения:
whatis
manpages
send process to background

2
12.07.2017, 23:18
2 ответа

Чтобы продолжить использовать set -e, но все же допустить известную ошибку, используйте это заклинание:

/bin/false || :

При этом используется оператор ||для «потребления» ошибки, чтобы она считалась нефатальной для среды, в которой активен set -e.

Вы уже используете 2>/dev/nullдля подавления стандартной ошибки, поэтому вы уверены, что ошибка исходит из строки, которую вы здесь цитируете? Кроме того, вместо использования execя предлагаю в качестве более удобочитаемой альтернативы:

if ! nc -z localhost 9091 1> /dev/null 2>&1; then
    port_free="yes"
fi

Поскольку код возврата ncпроверяется оператором if, это также безопасно после set -e.

2
27.01.2020, 22:03

Чтобы правильно перенаправить как поток ошибок, так и поток вывода в /dev/null, тем самым подавляя сообщение об ошибке, вам необходимо сгруппировать всю команду exec:

{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 || PORT_IS_FREE="yes"

execявляется встроенной оболочкой, поэтому мне трудно предсказать, как она себя поведет, однако я предполагаю, что даже при том, что она способна специально обрабатывать <и >, вся операция по-прежнему выполняется в нескольких шаги, потоки только последнего из которых перенаправляются. Кто-то, кто знает больше о работе exec, может пролить свет на это.

РЕДАКТИРОВАТЬ :Я не знаю, зачем вам нужно группировать фигурные скобки -для присваивания переменной, так как это одна команда, но вы все равно можете использовать фигурные скобки в сочетании с моими примерами, если хотите, вместо голого присваивания Я использовал.

Что касается игнорирования ошибки, вы можете завершить команду после перенаправления с помощью ;вместо использования ее статуса завершения через||:

{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 ; PORT_IS_FREE="yes"

Конечно, в этом случае есть проблема, что вы не сможете поймать никакую другую ошибку. Я только что попробовал, и после возникновения рассматриваемой ошибки статус выхода равен 1. Если другие коды возвращаются при других ошибках (, в чем я на самом деле сомневаюсь, поскольку 1 является очень общим кодом ошибки ), вы можете проверить 1. РЕДАКТИРОВАТЬ :Преимущество этого решения заключается в том, что он не завершается, когда код 1 возвращается после exec, когда используется set -e:

{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 || [ "$?" = 1 ] && PORT_IS_FREE="yes"

В противном случае вы можете использовать grep, чтобы попытаться сопоставить сообщение об ошибке, что, на мой взгляд, более надежно:

socketOpenOutput="$({ exec 3<>/dev/tcp/127.0.0.1/9091; } 2>&1`)"
socketOpenErrorCode="$?"
if [ "$socketOpenErrorCode" != 0 ]; then
    if ! echo "$socketOpenOutput" | grep 'connect\s*:\s*Connection refused' >/dev/null; then
        echo "An unexpected error happened when opening the socket!"
        exit 1
    fi
fi

PORT_IS_FREE="yes"

Это, однако, плохо работает с set -e.

2
27.01.2020, 22:03

Теги

Похожие вопросы