Як баш ставиться ">> ()"


9

Експериментуючи з перенаправленням виводу та підстановкою процесу, я натрапив на таку команду та її результат:

    me @ elem: ~ $ echo foo>> (кіт); ехо-бар
    бар
    me @ elem: ~ $ foo

(Так, порожній новий рядок в кінці є навмисним.)

Таким чином, баш ехо-смуги, друкує мою звичайну підказку, луна ехо, ехо - це новий рядок, і залишає мій курсор там. Якщо я знову натисніть Enter, він надрукує моє запит на новому рядку і залишить курсор за ним (як очікувалося, коли хтось натисне вводити в порожній командний рядок).

Я очікував, що він напише foo в дескриптор файлу, кішка читає його і лунає echo, друга смужка відлуння ехо, а потім повертається до командного рядка. Але це явно не так.

Невже хтось може пояснити, що відбувається?


Я хотів би запропонувати переглянути відповіді на це: unix.stackexchange.com/questions/182800/… Це пояснює подвійне перенаправлення і пояснило б, чому ви закінчуєте різні результати. І Муру, і Майкл Хормерс.
Немає часу

Щодо питання, в якому чітко йдеться про те, чому вихід підстановки процесу з’являється після підказок (а за деяких обставин взагалі не з’являється) в деяких версіях оболонки Bourne Again, див. Unix.stackexchange.com/questions/471987 .
JdeBP

Відповіді:


9

Можливо, ви побачите fooвідображення до bar, після barабо навіть після підказки, залежно від часу. Додайте невелику затримку, щоб отримати послідовний час:

$ echo foo > >(sleep 1; cat); echo bar; sleep 2 
bar
foo
$

barз'являється негайно, потім fooчерез одну секунду, потім наступна підказка через іншу секунду.

Що відбувається, це те, що bash виконує підстановку процесу на задньому плані.

  1. Основний процес bash запускає підзарядку для виконання sleep 1; catта встановлює трубу до неї.
  2. Основний процес bash виконується echo foo. Оскільки це не заповнює буфер труби, echoкоманда закінчується без блокування.
  3. Основний процес bash виконується echo bar.
  4. Основний процес bash запускає команду sleep 2.
  5. Тим часом, допоміжна команда запускає команду sleep 1.
  6. Приблизно через 1 секунду sleep 1повертається в підпроцес. Підпроцес переходить до виконання cat.
  7. cat копіює свій вхід на вихід (який відображається на екрані) і повертається.
  8. Підрозділ закінчив свою роботу, він виходить.
  9. Ще через секунду sleep 2повертається. Процес основної оболонки закінчується виконанням, і ви побачите наступний рядок.

3

Вам не потрібна заміна процесу, щоб отримати такий ефект. Спробуйте це:

( echo foo | cat & )

Ви отримаєте майже той самий результат (без цього bar, я залишаю це як вправу) і з тієї ж причини. В обох випадках catзапускається як фонове завдання. У моєму рядку це явно. У разі заміни процесу це також явно - це окремий процес, приєднаний до дескриптора файлу імен - але, можливо, це не так очевидно.

Дочірній процес не обов'язково закінчується до bashдруку наступного підказки. А оскільки його вихід буферний, він нічого не видає, поки не припиниться. У цей момент bash тільки надрукується $на stderr, і тепер фоновий процес закінчується після друку fooта нового рядка.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.