Экспериментируя с перенаправлением вывода и подстановкой процесса, я наткнулся на следующую команду и ее вывод:
me @ elem: ~ $ echo foo>> (кошка); эхо-бар бар me @ elem: ~ $ foo
(Да, этот пустой символ новой строки в конце является преднамеренным.)
Итак, bash echo's bar, печатает мою обычную подсказку, echo foo, echo - новую строку и оставляет мой курсор там. Если я нажму клавишу ввода еще раз, он выведет мою подсказку в новой строке и оставит после нее курсор (как и ожидалось, когда кто-нибудь нажмет клавишу ввода в пустой командной строке).
Я ожидал, что он напишет foo в файловый дескриптор, cat прочитает его и echo's foo, панель второго echo echo, а затем вернется в командную строку. Но это явно не тот случай.
Может кто-нибудь объяснить, пожалуйста, что происходит?
bash
shell
process-substitution
concurrency
Стэнли Ю.
источник
источник
Ответы:
Может
foo
отображаться доbar
, послеbar
или даже после запроса, в зависимости от времени. Добавьте небольшую задержку, чтобы получить согласованное время:bar
появляется сразу же, затемfoo
через одну секунду, затем следующая подсказка через следующую секунду.Происходит то, что bash выполняет подстановки процессов в фоновом режиме.
sleep 1; cat
и устанавливает для нее канал.echo foo
. Так как это не заполняет буфер канала,echo
команда завершается без блокировки.echo bar
.sleep 2
.sleep 1
.sleep 1
возвращается в подпроцесс. Подпроцесс продолжает выполнятьсяcat
.cat
копирует свой ввод в свой вывод (который отображается на экране) и возвращает.sleep 2
возвращается. Основной процесс оболочки завершает выполнение, и вы видите следующее приглашение.источник
Вам не нужна замена процесса, чтобы получить этот эффект. Попробуй это:
Вы получите почти такой же результат (без
bar
; я оставлю это как упражнение) и по той же причине. В обоих случаяхcat
запускается как фоновая задача. В моей строке это явно. В случае замены процесса это также явно - это отдельный процесс, связанный с дескриптором файла имени, - но, возможно, это не так очевидно.Дочерний процесс не обязательно завершается, прежде чем
bash
печатать следующее приглашение. И так как его вывод буферизован, он ничего не выводит, пока не завершится. В этот момент bash только что напечатал$
на stderr, и теперь фоновый процесс завершается после печатиfoo
и новой строки.источник