Вопрос по shell, bash, parallel-processing, unix – Есть ли способ сделать управление работой bash тихим?

35

Bash довольно многословен при выполнении заданий в фоновом режиме:

$ echo toto&
toto
[1] 15922
[1]+  Done                    echo toto

Поскольку я пытаюсь запускать задания параллельно и использовать выходные данные, я бы хотел найти способ заставить bash замолчать. Есть ли способ убрать этот лишний вывод?

Ваш Ответ

5   ответов
25

Примечание: следующее относится к Интерактивный Bash сессии. В Скрипты, сообщения управления заданиями:никогд напечатано.

Есть 2 основных сценария для Silencing сообщения контроля работы Bash:

Запуск и забыть:

Полезный ответ CodeGnome предлагает Включение фоновой команды в простой подоболочке - например,(sleep 10 &) - что эффективно заставляет замолчать сообщения управления заданиями - оба на заданиисоздани и на работе Прекращение.

У этого есть важный побочный эффект:

Используя оператор управления& Внутри недоработка, ты закрыть контроль фоновой работы - jobs не перечислю это, и ни%% (спецификация (ID) последней запущенной работы) ни$! (PID (последнего) процесса, запущенного (как часть) самой последней работы) будет отражать его. [1]

Для запускать и забывать сценарии, этон проблем:

Ты просто запустил фоновую работу, и вы позволите ему закончить самостоятельно (и вы уверены, что он работает правильно).

[1] Вероятно, вы можете сами искать процесс, ища в запущенных процессах те, которые соответствуют его командной строке, но это громоздко и непросто сделать надежным.

Launch-и-управления, позже:

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

убей эт, если нужно. синхронно ждать (в более поздний момент) для его завершения,

нужен другой подход:

Заглушитьсоздани сообщения управления заданиями обрабатываются ниже, но для того, чтобы молчать Прекращение сообщения контроля работыкатегорическ, Вы должны выключить опцию оболочки управления заданиями OFF:

set +m (set -m снова включается)Предостережени: Этоглобальные настройк с числом важные побочные эффекты, в частности:огда @Stdin для фоновых команд/dev/null вместо текущей оболочки. Сочетания клавиш для приостановки Ctrl-Z) и задержка ( Ctrl-Y) команда переднего плана отключена. Для полной истории смотритеman bash и (без учета регистра) поиска случаев «управления заданиями».

То молчатьсоздани сообщения контроля работы, заключите фоновую команду вгрупповая команда и перенаправить вывод stderr последнего на/dev/null

{ sleep 5 & } 2>/dev/null

В следующем примере показано, как тихо запустить фоновое задание, сохранив принципиальный контроль над заданием.

$ set +m; { sleep 5 & } 2>/dev/null # turn job-control option off and launch quietly
$ jobs # shows the job just launched; it will complete quietly due to set +m 

Если ты это сделаешьн хочу отключить опцию управления заданиями set +m), единственный способ заставить замолчать Прекращение сообщение управления заданием либоkill работа илиwait для этого

Предупреждение: Есть два крайних случая где этот метод все еще производит вывод:

Если фоновая команда пытается прочитать с stdinсраз. Если фоновая команда завершаетсясраз.

Чтобы начать работу тихо (как указано выше, но безset +m):

$ { sleep 5 & } 2>/dev/null

Тоwait тихо:

$ wait %% 2>/dev/null    # use of %% is optional here

Тоkill это тихо:

{ kill %% && wait; } 2>/dev/null

Дополнительныйwait необходим, чтобы сделать сообщение о завершении задания, которое обычно отображается Асинхронно Bash (во время фактического завершения процесса, вскоре после уничтожения) a Синхронное вывод изwait, который затем позволяет замолчать.

Но, как уже говорилось, если работа завершается сама по себе, сообщение управления заданием все равно будет отображаться.

1

Quiet.sh:

#!/bin/bash
[email protected] &

затем позвони, передав свою команду в качестве аргумента:

./quiet.sh echo toto

Вам может понадобиться поиграть с кавычками в зависимости от вашего ввода.

clever, но, похоже, не работает с некоторыми конструкциями bash. Пример: quiet.sh "[-e quiet.sh] || echo prout" static_rtti
"[email protected]" должен Определенно быть цитируемым. Это не будет работать большую часть времени - только для выполнения простых команд. Вы также можете просто использоватьbash -c 'cmds', илиbash -s <<"EOF" ormaaj
Еще лучше, использование () для запуска в подоболочке работает: (echo toto &) static_rtti
Таким образом, ты теряешь контроль над работой. Разветвленный процесс становится потомком init. Запуск отдельного скрипта не имеет такой проблемы, если вы действительно пытаетесь управлять параллельными объектами, но, похоже, это на самом деле не важно для вас. ormaaj
@ static_rtti, «хуже» - не совсем правильный способ описать это. Без кавычек[email protected] ведет себя так же, как и без кавычек$* со всеми теми же ошибками. Вы не хотите этих ошибок. Charles Duffy
1

нет. Это всегда будет отображать статус работы. Вы можете влиять, когда статус отображается с помощьюset -b.

Ничто не мешает вам использовать вывод ваших команд (через каналы, или хранить в нем переменные и т. Д.). Статус задания отправляется на управляющий терминал оболочкой и не смешивается с другими вводами / выводами. Если вы делаете что-то сложное с заданиями, решение состоит в том, чтобы написать отдельный скрипт.

Сообщения о вакансиях действительно являются проблемой, только если у вас есть, скажем, функции в вашем bashrc, которые используют управление заданиями, и вы хотите иметь прямой доступ к вашей интерактивной среде. К сожалению, с этим ничего не поделаешь.

-2

в bash) - направить весь вывод в / dev / null

    echo 'hello world' > /dev/null &

Выше не будет ничего, кроме идентификатора для процесса bg.

Это ничего не подавляет, кроме самого вывода команды - «id для процесса bg» - это именно то сообщение управления заданием, которое OP хочет заставить замолчать. mklement0
36

доболочке, и это заставит замолчать сообщения управления заданиями. Например

(sleep 10 & )
@ Dave: Спасибо, что заставили меня копать глубже. Позвольте мне подвести итог по-другому:(sleep 10 &) удобно отключает как создание, так и завершение сообщений, но вы теряете контроль над фоновым заданием. Чтобы избежать этого, используйте{ sleep 10 & } 2>/dev/null чтобы заставить замолчатьсоздани сообщение и используйте либоwait илиkill аналогично, чтобы заставить замолчать Прекращение сообщение (которое не всегда может быть вариантом). В качестве альтернативы,set +m может использоваться, чтобы категорически заставить замолчать сообщения завершения, что, однако, имеет много потенциально нежелательных побочных эффектов. У моего ответа (надеюсь) есть полная история. mklement0
Я так и сделал (см. Комментарии к принятому ответу). static_rtti
Блестящий и простой. Благодарност sehe
@ CodeGnome Я на самом деле не понимал первоначальный ответ, пока я не догадался о «скобках в bash», и обнаружил, что именно паренсы сделали его подоболочкой. (До этого я думал, что именно амперсанд сделал его подоболочкой.) jessepinho
@ mklement0 Хотя ваше предложение технически верно, оно не отвечает на вопрос. Конструкция {command &} 2> / dev / null скрывает начальное сообщение управления заданием, но нет способа подавить сообщение «[1] - Done» после завершения спящего режима. Dave

Похожие вопросы