Выполнение команд 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
причина, по которой я спрашиваю, заключается в том, что я хочу запустить фоновый процесс как часть команды tab-completion, поэтому вывод этой команды должен быть непрерывным, чтобы иметь какой-либо смысл.
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
редактировать
как подсказано @ 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 не является "waitable" в текущей интерактивной оболочке. Единственное решение, которое сработало для меня, - использовать мою собственную функцию ожидания, которая очень проста:
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