Sh команда никогда не заканчивается внутри NodeJS + Typescript (пока внутри оболочки) - PullRequest
0 голосов
/ 13 июля 2020

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

# Shell Script

(docker logs -f container_name &) | grep -m 1 "Listening on 0.0.0.0:3000"
echo "It will reach this point without problems"

все работает нормально. Сценарий оболочки на некоторое время приостанавливается на этой строке, и в конечном итоге он позволяет сценарию продолжить работу, когда docker журналы контейнера содержат строку Listening on 0.0.0.0:3000.

Однако по какой-то причине он застревает, когда я то же самое внутри сценария Typescript (выполняется с ts-node на NodeJS) (и я проверил из оболочки, что журналы контейнера достигли строки 'готово'):

import { execSync } from 'child_process'

console.log('Before exec, waiting for service to be ready')
execSync('(docker logs -f container_name &) | grep -m 1 "Listening on 0.0.0.0:3000"')
console.log('After exec, service ready')  // I never reach this point

Я пробовал этот же код с более простым примером, вместо использования docker logs, просто выполняя cat над файлом ... и он отлично работает, как в оболочке.

import { execSync } from 'child_process'

console.log('Before exec, waiting for service to be ready')
execSync('(cat filename &) | grep -m 1 "line to wait for"')
console.log('After exec, we found the coincidence')  // We reach this point as expected

И это часть, которую я не полностью get, что особенного во взаимодействии между docker и скриптом Typescript. Он работает, как ожидалось, в POSIX Shell, он работает, как ожидалось, с Typescript, когда команда немного проще (с cat) ... но она застревает для указанного c случая, который я предлагаю здесь (он не трескается sh тоже, я пробовал использовать неправильное имя контейнера, и в этом случае он вылетает, он не застревает).

Есть идеи? Спасибо за ваше время.

PS: Я попытался инкапсулировать команду в небольшой сценарий оболочки (а затем вызвать сценарий оболочки из NodeJS) ... и он тоже зависает. Итак ... возможно ли, что NodeJS имеет некоторую ошибку, вызывающую проблемы для команд, выполнение которых занимает слишком много времени?

1 Ответ

0 голосов
/ 14 июля 2020

Согласно документам execSyn c, он не вернется, пока порожденный процесс не будет полностью закрыт. Кажется, что docker logs -f... не завершается, и nodeJs этого ждет.

Этот другой подход должен работать (предположим, что ваша сеть доступна с хоста):

import { execSync } from 'child_process'

console.log('Before exec, waiting for service to be ready')
execSync('while (! curl localhost:8000 -I -s -q >/dev/null); do sleep 1; done')
console.log('After exec, service ready')
...