Проблемы с буферизацией s sh stderr без -tt - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь запустить сценарий bash удаленно, используя s sh, который выводит как на stderr, так и на stdout. Когда я нормально работаю в терминале, я получаю выходные данные по порядку. Но при запуске с s sh я этого не делаю, например:

$ ssh -T user@host bash <<< "echo hi >&2 && echo bye"
bye
hi

stderr откладывается до окончания stdout. Это контрастирует с большинством вещей, которые я видел в Интернете о различиях в буферизации между stderr и stdout, в которых указано, что stderr не буферизован (поэтому будет выводиться первым).

Но, несмотря на это, почти все, что я пытаюсь, не удается получить строки для вывода по порядку. Я пробовал использовать stdbuf -e0 -o0 -i0 практически для каждой части команды (до s sh, до bash, до эха). Я пробовал разные способы передачи команды (с bash -c, без bash вообще).

Я обнаружил, что ДЕЙСТВИТЕЛЬНО работает последовательно, если я прохожу - tt к s sh. Но использование -tt, похоже, добавляет банку с червями, и я бы предпочел этого не делать, если это возможно.

Есть ли другие способы сделать буферизацию вывода s sh более «нормальной»?

1 Ответ

1 голос
/ 04 августа 2020

Небуферизация stderr означает, что данные немедленно записываются в fd, но он не может гарантировать, что записанные данные будут обработаны получателем (pty, socket, pipe, ...).

For ssh -T, см. Этот пример (в Debian Linux):

[STEP 103] # ssh -T 127.0.0.1 'ls -l /proc/$$/fd'
total 0
lr-x------ 1 root root 64 Aug  4 13:59 0 -> pipe:[4610144]
l-wx------ 1 root root 64 Aug  4 13:59 1 -> pipe:[4610145]
l-wx------ 1 root root 64 Aug  4 13:59 2 -> pipe:[4610146]
lr-x------ 1 root root 64 Aug  4 13:59 3 -> /proc/23662/fd
[STEP 104] #

Как видно, sshd использует 3 канала для связи со своим дочерним процессом (таким образом, sshd может различие guish между данными stdout и данными stderr). Для ребенка гарантируется, что данные, записанные в stderr, будут немедленно отправлены в конвейер, но решение о том, когда данные будут обработаны, полностью зависит от процесса sshd. ( ОБНОВЛЕНИЕ : и даже после того, как sshd отправит данные обратно клиенту ssh, клиенту ssh по-прежнему решать, когда он обработает полученные данные.)

Что касается ssh -tt, ребенку будет выделен ребенок. Stdin, stdout и stderr дочернего процесса будут открыты на pty, и sshd не может различать guish между данными stdour и данными stderr, поэтому результат ожидается.

Для проверки ssh -tt не может различать guish между данными стандартного вывода и данными стандартного потока:

[STEP 109] # ssh -T 127.0.0.1 'echo hi; echo bye >&2'
hi
bye
[STEP 110] # ssh -T 127.0.0.1 'echo hi; echo bye >&2' 2> /dev/null
hi
[STEP 111] #
[STEP 112] # ssh -tt 127.0.0.1 'echo hi; echo bye >&2'
hi
bye
Connection to 127.0.0.1 closed.
[STEP 113] # ssh -tt 127.0.0.1 'echo hi; echo bye >&2' 2> /dev/null
hi
bye
[STEP 114] #
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...