Создать URL из вывода

Чтобы правильно перенаправить как поток ошибок, так и поток вывода в /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.

0
09.03.2021, 16:44
2 ответа
awk '{ line=(line?line"&":"") "ids="$0 }
END{ print "https://api.example.com/"line }' infile
1
18.03.2021, 22:26

Вы можете сделать это с простой оболочкой:

p=
for i in aa bb cc; do
  p="$p${p:+&}ids=$i"
done
url="https://api.example.com/?$p"

Конечно, вы также можете написать это в одной строке. Это создает параметры в $pи добавляет разделитель &, когда $pне пуст.

Если ваши параметры находятся в файле infile, вы можете получить их с помощью подстановки команд.

p=
for i in $(cat infile); do
  p="$p${p:+&}ids=$i"
done
url="https://api.example.com/?$p"
1
18.03.2021, 22:26

Теги

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