Подтвердить что ты не робот

Выполнение команд 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

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

4b9b3361

Ответ 1

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

(echo "Hello I'm a background task" &)

Ответ 2

Вам придется окружить его суб-оболочкой или группой процессов (т.е. { ... }).

/home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null
Hello I'm a background task
/home/shellter $

IHTH

изменить

как подсказывает @Mark downvote, я исследовал, что это не работает корректно в bash. Это работает, как показано в разделе ksh93.

Занято прямо сейчас, но я обновлю этот ответ тем, что я включил в комментарии к этому, и ответ @Tizord, но я не вижу легкого ответа на то, как перенаправить std-err из фоновой задачи. (Возможно, это возможно с помощью exec)

Ответ 3

Создав ответ @shellter, это сработало для меня:

[email protected]:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1;
Hello I'm a background task
[email protected]:~$

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

Ответ 4

Основываясь на приведенном выше ответе, если вам нужно разрешить stderr выполнить команду:

f() { echo "Hello I'm a background task" >&2; }
{ f 2>&3 &} 3>&2 2>/dev/null

Ответ 5

Try:

[email protected]:~$ read < <( echo "Hello I'm a background task" & echo $! )
[email protected]:~$ echo $REPLY
28677

И вы скрыли как вывод, так и PID. Обратите внимание, что вы все равно можете получить PID из $REPLY

Ответ 6

Извините за ответ на старое сообщение, но я считаю, что это полезно для других, и это первый ответ на Google.

У меня возникла проблема с этим методом (подоболочки) и с использованием "wait". Однако, когда я запускал его внутри функции, я смог это сделать:

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 секунд, прежде чем я верну свой запрос.

Ответ 7

Решение подоболочки работает, но я также хотел, чтобы можно было ждать фоновых заданий (и не иметь сообщение "Готово" в конце). $! из подоболочки не является "ожидаемым" в текущей интерактивной оболочке. Единственное решение, которое сработало для меня, было использовать мою собственную функцию ожидания, что очень просто:

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[*]}

Достаточно легко.