#bash
#bash
Вопрос:
Что !<
означает в этом скрипте bash и почему он указывает на файл, который не существует?
bash -c 'while !</dev/tcp/db/5432; do sleep 1; done; npm start'
Заранее спасибо за ваше время!
Комментарии:
1. Обратите внимание, что PostgreSQL поставляется с
pg_isready
командой, которую следует использовать вместо такого рода взлома (проверяет не только доступность сокета, но и то, что база данных действительно пригодна для использования)..
Ответ №1:
!
является оператором отрицания. Пример:
while ! false; do
echo "inside while loop"
sleep 1
done
будет находиться внутри цикла вечно, поскольку ! false
всегда имеет значение true .
<
это другой оператор. Он сообщает bash прочитать указанный файл. Он будет успешным (возвращает нулевой код выхода), если файл существует и доступен для чтения. Без левого операнда результаты чтения будут отброшены. Пример: проверка наличия /tmp/sample_file
:
if < /tmp/sample_file; then echo 'file exists'; fi
Таким образом, ваш код будет выполняться sleep 1
в цикле, пока /dev/tcp/db/5432
не может быть прочитан.
Теперь примите во внимание, что /dev/tcp/
это специальный путь, и доступ /dev/tcp/db/5432
означает попытку подключения к хосту db
через TCP-порт 5432.
Итак, логика вашего цикла while такова: «спящий режим, пока postgresql в базе данных хоста не будет готов» (5432 — порт по умолчанию для PostgreSQL).
Ответ №2:
Вы должны прочитать это вместе с файлом, который находится после <
. Синтаксис < file
открывает содержимое файла для перенаправления ввода для любого приложения для чтения поверх стандартного ввода.
В вашем конкретном синтаксисе </dev/tcp/db/5432
(tcp-порт на удаленном хосте) конструкция определяется только для проверки, доступен ли файл для открытия для чтения. Команда вернет код успешного завершения 0
, если файл доступен, и !
аннулирует возвращенный код завершения.
Итак, в основном цикл while в вашем примере видит while 1
, доступен ли файл, что в контексте оболочки означает возврат ненулевого кода выхода, который вообще не позволяет спящему режиму произойти. Не совсем ясно, было ли ваше намерение перейти в режим ожидания, пока файл не будет доступен для открытия, или наоборот.
Комментарии:
1. Я бы также упомянул, что
/dev/tcp/db/5432
это не обычный файл, а вызываемый tcp-порт на удаленном хостеdb
.2. Я думаю, что между! и < также?