Выполнение команд bash в фоновом режиме без печати идентификаторов заданий и процессов
запустить процесс в фоновом режиме в 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
причина, по которой я спрашиваю, заключается в том, что я хочу запустить фоновый процесс как часть команды завершения вкладки, поэтому вывод этой команды должен быть непрерывным, чтобы иметь какой-либо смысл.
8 ответов:
не связано с завершением, но вы можете подавить этот вывод, поместив вызов в подобласть:
(echo "Hello I'm a background task" &)
вам придется окружить его суб-оболочкой или группой процессов (т. е.
{ ... }
)./home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null Hello I'm a background task /home/shellter $
IHTH
edit
как подсказано @ Mark 's downvote, я исследовал, что это не работает правильно в
bash
. Это работает, как показано в разделеksh93
.занят прямо сейчас, но я обновлю этот ответ тем, что я включил в комментарии к этому и ответу @Tizord, но я не вижу простого ответа на то, как перенаправить std-err от фоновой задачи. (Это, вероятно, возможно с
exec
манипуляции)
отталкиваясь от ответа @shellter, это сработало для меня:
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:~$
Я не знаю, почему это происходит, но я вспомнил из старого сообщения, которое отрицает, что bash не выводит идентификаторы процесса.
основываясь на приведенном выше ответе, если вам нужно разрешить stderr пройти через команду:
f() { echo "Hello I'm a background task" >&2; } { f 2>&3 &} 3>&2 2>/dev/null
попробуй:
user@host:~$ read < <( echo "Hello I'm a background task" & echo $! ) user@host:~$ echo $REPLY 28677
и Вы скрыли оба выход и PID. Обратите внимание, что вы все еще можете получить PID от $REPLY
извините за ответ на старый пост, но я считаю, что это полезно для других, и это первый ответ на Google.
у меня была проблема с этим методом (подоболочки) и использованием 'wait'. Однако, как я запускал его внутри функции, я был в состоянии сделать это:
function a { echo "I'm background task " 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 секунд, прежде чем я получу свое приглашение обратно.
решение subshell работает, но я также хотел иметь возможность ждать на фоновых заданиях (и не иметь сообщения "Сделано" в конце).
$!
from a subshell не является "ожидаемым" в текущей интерактивной оболочке. Единственным решением, которое сработало для меня, было использовать мою собственную функцию ожидания, которая очень проста: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[*]}
достаточно легко.
на основе ответ, Я придумал более лаконично и правильно:
silent_background() { { 2>&3 "$@"& } 3>&2 2>/dev/null disown &>/dev/null # Prevent whine if job has already completed } silent_background date