Запустить процесс в фоновом режиме в bash довольно просто.
$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+ Done echo "Hello I'm a background task"
Однако вывод подробный. В первой строке печатается идентификатор задания и идентификатор процесса фоновой задачи, затем у нас есть выходные данные команды, наконец, у нас есть идентификатор задания, его статус и команда, которая инициировала задание.
Есть ли способ подавить вывод выполнения фоновой задачи таким образом, чтобы вывод выглядел точно так же, как без амперсанда в конце? Т.е.:
$ echo "Hello I'm a background task" &
Hello I'm a background task
Причина, по которой я спрашиваю, заключается в том, что я хочу запустить фоновый процесс как часть команды завершения табуляции, поэтому вывод этой команды должен быть непрерывным, чтобы иметь какой-либо смысл.
bash
bash-completion
Алекс Сперлинг
источник
источник
Ответы:
Не связано с завершением, но вы можете подавить этот вывод, поместив вызов в подоболочку:
(echo "Hello I'm a background task" &)
источник
wait
фоновое задание завершилось.Основываясь на ответе @hellter, это сработало для меня:
tyler@Tyler-Linux:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1; Hello I'm a background task tyler@Tyler-Linux:~$
Я не знаю причин этого, но я вспомнил из старого сообщения, что disown не позволяет bash выводить идентификаторы процессов.
источник
;
в конце. (без сна) . 2. НО заметил, что когда я добавилecho STDERR 2>&1
на "следующую" строчку, то[1]+ Done ...
появилась вещь! . 3. Мое решение (как я уже отметил) работаетksh
иecho STDERR 2>&1
выдает только вывод STDERR. Что ж, живи и учись для нас обоих. Всем удачи.В некоторых более новых версиях bash и в ksh93 вы можете окружить его суб-оболочкой или группой процессов (т.е.
{ ... }
)./home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null Hello I'm a background task /home/shellter $
источник
ksh93+
качестве основной оболочки. Этот код работает, как и было обещано в ksh. но поскольку OP помечен,bash
я понимаю ваш дв. Смотрите результаты тестирования bash в ответе @Tyzoid. Всем удачи!wait $!
который, похоже, не относится к принятому ответу.Основываясь на приведенном выше ответе, если вам нужно разрешить stderr проходить из команды:
f() { echo "Hello I'm a background task" >&2; } { f 2>&3 &} 3>&2 2>/dev/null
источник
disown
.Основываясь на этом ответе , я придумал более лаконичный и правильный:
silent_background() { { 2>&3 "$@"& } 3>&2 2>/dev/null disown &>/dev/null # Prevent whine if job has already completed } silent_background date
источник
Пытаться:
user@host:~$ read < <( echo "Hello I'm a background task" & echo $! ) user@host:~$ echo $REPLY 28677
И вы скрыли и вывод, и PID . Обратите внимание, что вы все еще можете получить PID из $ REPLY
источник
Извините за ответ на старый пост, но я считаю, что это полезно для других, и это первый ответ в Google.
У меня возникла проблема с этим методом (подоболочки) и с использованием «подождите». Однако, когда я запускал его внутри функции, я смог сделать это:
function a { echo "I'm background task $1" sleep 5 } function b { for i in {1..10}; do a $i & done wait } 2>/dev/null
И когда я его запускаю:
$ b I'm background task 1 I'm background task 3 I'm background task 2 I'm background task 4 I'm background task 6 I'm background task 7 I'm background task 5 I'm background task 9 I'm background task 8 I'm background task 10
И есть задержка в 5 секунд, прежде чем я верну свою подсказку.
источник
Решение подоболочки работает, но я также хотел иметь возможность ждать фоновых заданий (и не иметь в конце сообщения «Готово»).
$!
из подоболочки не является "ожидаемым" в текущей интерактивной оболочке. Единственное решение, которое сработало для меня, - это использовать мою собственную функцию ожидания, которая очень проста:myWait() { while true; do sleep 1; STOP=1 for p in $*; do ps -p $p >/dev/null && STOP=0 && break done ((STOP==1)) && return 0 done } i=0 ((i++)); p[$i]=$(do_whatever1 & echo $!) ((i++)); p[$i]=$(do_whatever2 & echo $!) .. myWait ${p[*]}
Достаточно просто.
источник