A função retorna, mas a substituição do comando é bloqueada, porque você criou um trabalho em segundo plano, mas ainda tem o stdout fd aberto. Basta fechá-lo adicionando >/dev/null
antes do &
.
#!/bin/bash
function start {
leafpad >/dev/null &
echo $!
}
PID=$(start)
echo "PID is $PID"
Se você deseja que seu processo também tenha stdin, stdout, stderr fechado, use o seguinte:
leafpad >/dev/null 0>&1 2>&1 &
Isso fechará stdin (0), stdout (1) e stderr (2) e depois o plano de fundo (&). Além disso, ao usar esses redirecionamentos de fluxo , não se esqueça de que eles são "enganados", ou seja, duplicados na ordem de execução.
1>/dev/null 2>&1
e
2>&1 1>/dev/null
não são os mesmos ! No primeiro, você está duplicando um fluxo para / dev / null (que é o que você deseja); no segundo, você está duplicando / dev / stdout no stderr e, em seguida, fechando o stdout. Portanto, qualquer mensagem enviada para stderr
aparecerá no seu console.
n>&-
Onden
está o descritor de arquivo./dev/null
não leva a erros de E / S quando um processo tenta gravar seu stdout, mas descobre que1
é um FD inválido. Portanto, a terminologia no post está errada, não a programação real do bash. (Na verdade, duplicando FD 1 a 0 significa que stdin será um arquivo descritor aberto comO_RDONLY
, o que provavelmente vai dar um erro (em vez do desejado no-bytes disponível no mercado) quando as tentativas do processo para ler.), Por exemplowc >/dev/null 0>&1
->wc: standard input: Bad file descriptor
exec <&- >&- <>/dev/null >&0
lida com stdin / out bastante exaustivamente. Faz diferençazsh
pelo menos o que concatenará todas as aberturas no mesmo descritor automaticamente quando multios estiver definido.