bash -i поведение и «почему мой терминал висел?»

Это происходит на каждом дистрибутиве, который я пробовал:

 $ cat |  bash -i
 bash-3.2 $ ls
 foo bar
 Баш-3,2 $

И теперь сессия висела. То есть, вы получаете одну команду, а затем вам достаточно закрыть окно терминала. SIGTERM (aka ^ C) пойман bash, но он не вернет вас в рабочую оболочку.

Я предполагаю, что это имеет какое-то отношение к -i заставляя bash сражаться с кошкой для контроля над tty, но я не могу найти ничего окончательного. Может ли кто-нибудь объяснить, что происходит? И как мне автоматизировать ввод в программу, которая запускает execlp("/bin/bash", "bash", "-i") без зависания? Должен ли я писать ожидающую программу, которая обрабатывает tty vagaries?

Короткий ответ: да, вам придется использовать Expect.

Что касается того, почему он не работает: на основе его поведения bash -i включает readline (даже с --noediting ), который плохо работает с трубами. Также, как представляется, настройка режимов терминала (включая неблокирующий режим) через stdout вместо stdin , что означает, что вы теряете ожидаемое поведение большинства управляющих символов. (Это, однако, не читает tty напрямую.)

Сторона примечания: ^C отправляет SIGINT , а не SIGTERM . Оба они, однако, оказались в интерактивном режиме ( -i ); SIGHUP работает, чтобы убить его.