Тихо запустить задание в фоновом режиме

12

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

(команда &) &> / dev / null

Однако это удаляет возможность перехватывать, когда процесс завершается ( trap child_done CHLD).

Как я могу иметь оба?

Tyilo
источник

Ответы:

5

диспетчер задач может вам помочь.

Как в freshmeat.net :

диспетчер задач - это пакетная система Unix, в которой буферные задачи выполняются одна за другой. Количество заданий, запускаемых одновременно, может быть установлено в любое время. Каждый пользователь в каждой системе имеет свою очередь заданий. Задачи выполняются в правильном контексте (в очереди) из любой оболочки / процесса, и его результаты / результаты можно легко отслеживать. Это очень полезно, когда вы знаете, что ваши команды зависят от большого количества оперативной памяти, большого объема использования диска, дают много выходных данных или по любой причине лучше не запускать их все одновременно, в то время как вы хотите сохранить Ваши ресурсы заняты для максимальной выгоды. Его интерфейс позволяет легко использовать его в скриптах.

Диспетчер задач доступен в Debian , Ubuntu и других дистрибутивах.

Это позволяет вам иметь очередь задач для запуска и получать доступ к их выводам только по желанию.

Например:

$ tsp sleep 5
0 
$ tsp sleep 5 
1
$ tsp
ID   State      Output               E-Level  Times(r/u/s)   Command [run=1/1]
2    running    /tmp/ts-out.ZWn6Le                           sleep 5
1    finished   /tmp/ts-out.Fhlcle   0        5.00/0.00/0.01 sleep 5

Если вы выполняете много заданий в фоновом режиме, это определенно вам поможет.

Вы можете запускать их последовательно или в заданном количестве слотов. Вы также можете установить зависимости между задачами (запускать задачу 1, только если задача 0 выполнена успешно).

Рауль Салинас-Монтеагудо
источник
3

Вот как это сделать в обоих случаях {ba,z}sh.

Использование функции помогает не необходимости сохранять и восстанавливать состояние zsh«S monitorпеременного путем использования setopt local_options.

# Run the command given by "$@" in the background
silent_background() {
  if [[ -n $ZSH_VERSION ]]; then  # zsh:  /superuser//a/1285272/365890
    setopt local_options no_notify no_monitor
    "$@" &
  elif [[ -n $BASH_VERSION ]]; then  # bash: /programming//a/27340076/5353461
    { 2>&3 "$@"& } 3>&2 2>/dev/null
  else  # Unknownness - just background it
    "$@" &
  fi
}

Используя это следующим образом:

trap 'echo child done' CHLD
silent_background sleep 1

Будет выдавать ожидаемое child doneсообщение.

Том Хейл
источник
см. обнадеживающее объяснение на сайте unix.stackexchange.com/q/456549/4778 .
Ctrl-Alt-Delor
2

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

Вот цитата из «Справочного руководства Bash», глава «Управление заданиями», раздел первый.

Оболочка связывает JOB с каждым конвейером. Он хранит таблицу выполняемых в данный момент заданий, которая может быть указана с помощью jobsкоманды. Когда Bash запускает задание асинхронно, он печатает строку, которая выглядит следующим образом:

[1] 25647

это означает, что это задание № 1 и что идентификатор процесса последнего процесса в конвейере, связанного с этим заданием, равен 25647. Все процессы в одном конвейере являются членами одного и того же задания. Bash использует абстракцию JOB в качестве основы для управления заданиями.

Обратите внимание, что сценарий оболочки не отображает это уведомление.

$ cat test
#!/bin/bash

true & echo true
$ ./test
true

По факту

Zsh

Документация Zsh содержит аналогичные указания по поводу этих уведомлений, см. man 1 zshmiscРаздел «ЗАДАНИЯ». Эти уведомления не отображаются, когда управление заданиями отключено.

МОНИТОР ( -m , ksh: -m )

    Разрешить контроль работы. Устанавливается по умолчанию в интерактивной оболочке.

zsh_prompt % setopt no_monitor
zsh_prompt % true & echo true
true
zsh_prompt %
zsh_prompt % 

удар

Кажется, что Bash всегда отображает, например [1] 25647. «Окончательное уведомление», например [1]+ Done true, не отображается, когда управление заданиями отключено.

bash_prompt $ true & echo true
[1] 25647
true
bash_prompt $ 
[1]+  Done                    true

Контроль работы отключен

bash_prompt $ set +m       # disable job control
bash_prompt $ true & echo true
[1] 25685
bash_prompt $
bash_prompt $

Вывод

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

Ресурсы

Fólkvangr
источник
1

Вы можете вызвать zshкак неинтерактивную оболочку для отключения уведомлений о заданиях.

zsh -c '
   trap "echo trapped child_done" CHLD
   sleep 5 &
   #wait
   sleep 10 # simulate other running cmds
   echo script done
'
над
источник
0

Смотрите следующий пример:

trap 'echo "DONE"' 0
{ find /usr & } &> /dev/null
wait

Это хорошо работает. Нет необходимости ( ): это делает ненужную подоболочку. { }просто группируем команды.

Жиль Квено
источник
Это печатает [2] 49591и [2] + 49591 exit 1 find /usr, когда это должно напечатать ни один из них!
Тило
Извините, неправильно понял ваш вопрос.
Жиль Квено
0

Это старый вопрос, но возможный ответ (в bash, не тестировался с zsh) - использовать управление заданиями в подоболочке: (command & wait)

Примечание: bash подавляет сообщения фонового задания начала / конца в подоболочке, и перенаправление не требуется.

Philippe
источник
Я думаю, что вы пропустили часть с ловушкой. Насколько я понимаю, вопрос о том, что подпроцесс должен быть запущен, что-то будет сделано во время выполнения суперпроцесса, а затем, когда подпроцесс завершится, должно быть выполнено что-то еще. С помощью вашего решения вы запускаете подпроцесс, ожидая его в подоболочке, а основная оболочка ожидает подоболочки. Это избавляет от сообщений, но вы не можете делать что-то параллельно.
Рафаэль Аренс
Нет, (sleep 5 & wait)задерживает 5 секунд.
Том Хейл,