Фоновые процессы смешивают порядок выполнения сценария оболочки

Может кто-нибудь объяснить мне, почему сценарий

echo one && echo two & echo three && echo four 

дает мне

 [1] 3692 three four one two [1]+ Done echo one && echo two 

По-видимому, все за фоновым процессом выводится первым, а строки кода в хронологическом порядке до того, как фоновый процесс печатается последним. Я наткнулся на это в сценарии, который я пытался написать, и не понимаю, почему он ведет себя так (althogh, я предполагаю, что за этим стоит какая-то изобретательность).

Я уже выяснил, что могу предотвратить это с помощью скобок:

 echo one && (echo two &) echo three && echo four 

дает

 one two three four 

а также

 echo one && (sleep 2 && echo two &) echo three && echo four 

дает

 one three four two 

Потому что вторая строка спит в фоновом режиме и, следовательно, выводит, когда первые строки уже выполнены.

Но почему скобки имеют такой эффект?

Бонусный вопрос: почему скобки предотвращают вывод фонового PID?

  • Избегайте расширения обратной косой черты с эхом в тире
  • Как отключить «auto cd» в zsh с помощью oh-my-zsh
  • init-скрипты в autoyast для автоматического развертывания сервера Suse Linux
  • Может ли оболочка предупредить меня, если программа ждет стандартного ввода?
  • Fish-Shell не сохранит мои псевдонимы
  • Создать псевдоним для каталога рабочего стола
  • Как изменить разрешения от пользователя root для всех пользователей?
  • Вход в систему с конкретной оболочкой при входе в терминал
  • 2 Solutions collect form web for “Фоновые процессы смешивают порядок выполнения сценария оболочки”

     echo one && echo two & echo three && echo four 

    Имейте в виду, что это анализируется как

     echo one && echo two & echo three && echo four 

    Я предполагаю, что команды echo успешны (они будут терпеть неудачу только в случаях краев, таких как перенаправление на файл на полный диск). Таким образом, этот фрагмент выполняет две задачи параллельно: один печатает строки one и two , а другой печатает строки three и four . Вмешательство one и two с three и four не гарантируется и может варьироваться от системы к системе, от оболочки до оболочки и от вызова к вызову. Для подобного примера игрушек вы можете наблюдать воспроизводимые результаты в слегка загруженной системе, но это не то, на что вы можете рассчитывать.

     echo one && (echo two &) echo three && echo four 

    Вы изменили синтаксический анализ: здесь в фоновом режиме выполняется только команда echo two . Это гарантирует, что one будет выводиться первым, и, как и до three , всегда будет до four , но размещение two может быть где угодно после one .

    Оболочка только печатает сообщение о фоновых процессах, если они запускаются из основного процесса оболочки, а не когда они запускаются в подоболочке. Скобки создают подоболочку, поэтому (echo two &) не вызывает оболочку для печати любого сообщения. Это создает фоновый процесс, но не фоновая работа .

     echo one && (sleep 2 && echo two &) echo three && echo four 

    В этом фрагменте фоновое задание засыпает в течение 2 секунд перед выдачей two . Это очень вероятно (но фактически не гарантировано), что two будут выдаваться после three и four .

    Часть 1

     echo one && echo two & echo three && echo four 

    Это можно переписать как

     echo one && echo two & echo three && echo four 

    Причина, по которой вы получаете three и four первых, – это просто то, что для того, чтобы обработать one и two операции и работать дольше, чем для печати three и four требуется больше времени.

    Вы можете видеть это немного более ясно, как это

     echo one && echo two & sleep 1 echo three && echo four 

    В этой ситуации вы получаете one и two , а затем через секунду three и four .

    Обратите внимание, что в исходном сценарии нет гарантии, что one и two не будут смешиваться с выходом из three и four , по- thonreee , даже с интерполированными словами, такими как thonreee или twfouro .

    Часть 2

     echo one && (echo two &) echo three && echo four 

    Это можно переписать как

     echo one && (echo two &) echo three && echo four 

    Здесь происходит то, что one печатается сразу, а затем two выстреливаются в подоболочку. Затем (последовательно) выполняется следующая строка, в результате получается three и four . В вашей конкретной ситуации подоболочка мала и достаточно быстра, чтобы их можно было напечатать до выхода three . Однако никаких гарантий этого нет.

    Часть 3

    Групповые утверждения скобок группируются в подоболочку. Амперсанд & применим к заявлению, но в этом случае вы использовали && для связывания двух команд вместе, поэтому их нужно рассматривать как один оператор.

    Возможно, вы должны использовать echo one; echo two echo one; echo two а не echo one && echo two ? Они очень разные. Точка с запятой ; разделяет две команды, которые затем запускаются независимо, но последовательно. Двойной амперсанд && соединяет две команды вместе как логические И , так что вторая будет работать только в том случае, если первая завершится успешно. Сравнить false; echo yes false; echo yes , false && echo yes , а true && echo yes . Затем поэкспериментируйте, заменив && ( логическое И ) на || ( логическое ИЛИ ).

    бонус

    Вы теряете уведомление о контроле работы, потому что у подоболочки нет управления заданиями.

    Interesting Posts

    Как получить свой собственный IP-адрес и сохранить его в переменной в сценарии оболочки?

    Как отправить все выходные данные на пейджер по умолчанию?

    Вывод трубы tcpdump с опцией buffer -B

    Получение «Ошибка протокола» при попытке создания символической ссылки в Docker

    Как переключить группу без запроса пароля?

    различные утилиты контрольных сумм предшествуют хешу с обратной косой чертой

    Размещение двоичных файлов ядра и источников для создания модуля ядра?

    Некоторая утечка памяти X.org с использованием проприетарного драйвера nvidia

    Что такое команда для поиска приоритета процесса в Linux?

    веб-камера с сыром

    Прочитайте каждую строку – BASH

    Удалить каталоги, содержащие определенный файл

    Как я могу поменять значок батареи в systray?

    Установлена ​​новая графическая карта NVidia, и теперь я не могу войти в систему

    Как я могу переместить мой / загрузочный раздел?

    Linux и Unix - лучшая ОС в мире.