Кошка, эхо и процесс замещения - PullRequest
3 голосов
/ 25 февраля 2020

В основном я пытаюсь понять разницу между этими командами:

cat <<< yolo | tee f.txt
echo yolo | tee t.txt

И этими командами:

cat <<< yolo > >(tee f.txt)
echo yolo > >(tee t.txt)

Первые две команды имеют одинаковый результат: "yolo" выводится на печать, и после этого терминал возвращает управление, что я и ожидал.

[user@localhost ~] $ cat <<< yolo | tee f.txt </p>

yolo

[user@localhost ~] $ echo yolo | tee t.txt

yolo

Но с заменой процесса происходит нечто странное с echo.

[user@localhost ~] $ cat <<< yolo>> (tee f.txt)

yolo

[user@localhost ~] $ echo yolo>> (tee t.txt)

[user@localhost ~] $ yolo

Терминал возвращает управление до вывода текста на печать. Почему я получаю управление раньше в этом случае?

Это должно иметь какое-то отношение к тому, как открываются процессы и как файловые дескрипторы передаются между процессами, но я вроде достиг пределы моих знаний.

Если я передам это чему-либо еще, все вернется к норме, например, echo yolo > >(tee t.txt) | cat.

Что еще более странно, это то, что xargs 'in echo работает ну:

[user@localhost ~] $ xargs echo <<< yolo>> (tee t.txt)

yolo

Но вы Можно сказать, что xargs является главной программой здесь, а не echo.

И если я использую подстановку процесса ввода с cat, я получаю смешанные результаты:

cat < <(echo yolo) > >(tee t.txt)

Иногда мне это дает:

[user@localhost ~] $ cat <<(echo yolo)>> (tee t.txt)

[user@localhost ~] $ yolo

И иногда это:

[user@localhost ~] $ cat <<(echo yolo)>> (tee t.txt)

yolo

Так что я думаю, что это может быть что-то делать с как быстро система выполняет команду, что делает ее непредсказуемой.

Означает ли это, что подстановка выходного процесса (например, tee в этом примере) выполняется в фоновом режиме?

1 Ответ

2 голосов
/ 25 февраля 2020

Ах, я думаю, что нашел это ...

Замена процесса ... Процесс list выполняется асинхронно , и его вход или выход отображается как имя файла ...

Как только команда (или разветвленный процесс завершается), управление возвращается к терминалу и отображается следующее приглашение. Я изначально подозреваю, что встроенный echo мог бы сыграть свою роль, но на самом деле это только исказило время. Т.е. один раз с использованием > >(tee t.txt), когда tee добирается до печати на консоль, точно не определено c.

В этом отношении попробуйте это (для вашего третьего примера):

$ cat <<< yolo > >(sleep 1; tee f.txt)
$ yolo

В отличие от:

$ { echo yolo; sleep 1 ;} > >(tee t.txt)
yolo
$

Разница в том, что >(list) замена процесса, как упоминалось, выполняется асинхронно. Попробуйте первый из двух примеров, даже с большим значением sleep, чтобы имитировать длительный процесс. Он будет зависать, пока вы продолжаете использовать свою оболочку (на самом деле, даже если вы прервете ее, в этом случае она будет переименована, но вы все равно увидите ее в списке процессов; примечание: "Команды выполняются как результат подстановки команд игнорирует сгенерированные клавиатурой сигналы управления заданиями SIGTTIN, SIGTTOU и SIGTSTP. " -> даже потеря терминала не приведет к их уничтожению, в отличие от примера асинхронного (&) ниже ).

Конвейеры с другой стороны:

Если конвейер не выполняется асинхронно (см. Списки), оболочка ожидает всех команд в конвейере завершить.

Оболочка не возобновляет управление (следующая команда не выполняется), пока все команды из конвейера не завершат выполнение.

Попробуйте:

$ echo yolo |  (sleep 1; tee f.txt)
yolo
$

в отличие от (аналогично использованию >(list)):

echo yolo |  ((sleep 1; tee f.txt) &)
$ yolo

(двойная вложенная оболочка на самом деле не нужна, я просто использовал ее для подавления сообщений управления заданиями в работающей оболочке).

...