Как получить код выхода socat при передаче stdin в него?

Вопрос или проблема

Я выполняю команды в контейнере Docker, используя socat, и хочу получить код завершения кода, выполненного в контейнере.

Вот что я пробовал:

$ docker run --rm -itd --name test123 ubuntu
$ echo "ls" | socat EXEC:"docker attach test123",pty - &> /dev/null
$ echo $?
0
$ echo "foobar" | socat EXEC:"docker attach test123",pty - &> /dev/null
$ echo $?
0

Как вы можете видеть, это не работает правильно, потому что код завершения команды foobar должен явно быть ненулевым.

$ socat -V
socat version 1.8.0.1 on 
   running on Darwin version

man bash, в разделе VARIABLES, показывает, что вам нужно:

PIPESTATUS
Переменная массива (см. Массивы), содержащая список кодов завершения
значений процессов в самом недавнем выполненном
фоновом пайплайне (который может содержать только одну команду).

Ответ или решение

Для получения кода выхода команды, выполненной в контейнере Docker с использованием socat, необходимо правильно обрабатывать конвейеры и использовать специальную переменную в Bash, которая сохраняет статусы выхода команд в последнем выполненном конвейере.

Проблема

В вашем случае, когда вы используете socat для отправки команды в Docker-контейнер с помощью echo, код выхода команды не отражается должным образом. Это происходит потому, что socat и docker attach обрабатываются в рамках одного конвейера, и echo $? возвращает статус выхода команды echo, что всегда 0.

Решение

Используйте массив PIPESTATUS, который в Bash хранит коды выхода всех команд, участвующих в последнем выполненном конвейере. Ниже приведен пример, как это можно реализовать:

# Запустите Docker контейнер
docker run --rm -itd --name test123 ubuntu

# Отправка команды в контейнер с использованием socat
echo "ls" | socat EXEC:"docker attach test123",pty - > /dev/null
# Получение кода выхода команды ls
exit_code_ls=${PIPESTATUS[0]}
echo "Exit code of ls: $exit_code_ls"

# Отправка неправильной команды
echo "foobar" | socat EXEC:"docker attach test123",pty - > /dev/null
# Получение кода выхода команды foobar
exit_code_foobar=${PIPESTATUS[0]}
echo "Exit code of foobar: $exit_code_foobar"

Объяснение кода

  1. docker run: Запускаем контейнер Ubuntu в фоновом режиме.
  2. echo "ls" | socat …: Команда ls отправляется в контейнер через socat.
  3. ${PIPESTATUS[0]}: Эта переменная содержит код выхода первой команды из конвейера, что в данном случае будет статус выполнения команды ls.
  4. > /dev/null: Отключает вывод в терминал, потенциально улучшая читаемость.

Важные моменты

  • Убедитесь, что в вашем контейнере установлены все необходимые команды.
  • Если вы используете команды, которые могут завершиться с ошибкой, настройте обработку ошибок для более надежной работы.
  • Следите за тем, что docker attach работает с активным терминалом и не может обрабатывать команды, которые не выполняют ввода/вывода через STDIN/STDOUT корректно.

Заключение

Используя переменные Bash и правильную обработку кодов выхода, вы сможете отслеживать успешность выполнения команд в Docker контейнерах с помощью socat. Этот подход не только обеспечивает правильность обработки ошибок, но и улучшает контроль над процессами, что особенно важно в разработке и эксплуатации приложений.

Оцените материал
Добавить комментарий

Капча загружается...