bash
não deve imprimir o status do trabalho quando não é interativo.
Se isso for realmente para um bash
interativo, você pode fazer:
{ pid=$(sleep 20 >&3 3>&- & echo "$!"); } 3>&1
Queremos que o stdout de sleep
vá até onde estava antes, não o canal que alimenta a variável $pid
. Então, salvamos o stdout outer no descritor de arquivo 3 ( 3>&1
) e o restauramos por sleep
dentro da substituição do comando. Então pid=$(...)
retorna assim que echo
termina porque não há mais nada com um descritor de arquivo aberto no canal que alimenta $pid
.
No entanto, note que, como ele é iniciado a partir de um subshell (aqui em uma substituição de comando), o sleep
não será executado em um grupo de processos separado. Portanto, não é o mesmo que executar sleep 20 &
em relação a E / S para o terminal, por exemplo.
Talvez seja melhor usar um shell que suporte a geração de empregos em segundo plano deserdados , como zsh
, onde você pode fazer:
sleep 20 &! pid=$!
Com bash
, você pode aproximá-lo com:
{ sleep 20 2>&3 3>&- & } 3>&2 2> /dev/null; pid=$!; disown "$pid"
bash
produz o [1] 21578
para stderr. Então, novamente, nós salvamos stderr antes de redirecionar para / dev / null e restaurá-lo para o comando sleep
. Dessa forma, o [1] 21578
vai para /dev/null
, mas o sleep
é como sempre.
Se você for redirecionar tudo para / dev / null, pode simplesmente fazer:
{ apt-get update & } > /dev/null 2>&1; pid=$!; disown "$pid"
Para redirecionar somente a stdout:
{ apt-get-update 2>&3 3>&- & } 3>&2 > /dev/null 2>&1; pid=$!; disown "$pid"