Por que a função não retorna até que o processo em segundo plano termine?

20

Considere este script:

#!/bin/bash
function start {
  leafpad &
  echo $!
}
PID=$(start)
echo "PID is $PID"

O script não continua além da sua chave de fechamento até que o processo leafpad termine, mesmo que seja um processo em segundo plano.

Por que isso? É possível iniciar um processo em segundo plano a partir de uma função?

    
por user234565 27.07.2015 / 01:05

1 resposta

21

A função retorna, mas a substituição de comandos bloqueia, porque você criou um job em background, mas ainda tem seu 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ê quiser que seu processo tenha também stdin, stdout, stderr fechado, use isto:

leafpad >/dev/null 0>&1 2>&1 &

Isto irá fechar stdin (0), stdout (1) e stderr (2) e, em seguida, fundo (&). Além disso, ao usar esses redirecionamentos de fluxo , não esqueça que eles estão "enganados", que meios duplicados na ordem de execução.

1>/dev/null 2>&1

e

2>&1 1>/dev/null

não são iguais! No primeiro, você está duplicando um fluxo para / dev / null (que é o que você quer), no último, você está duplicando / dev / stdout para stderr e, em seguida, fechando stdout. Portanto, qualquer mensagem enviada para stderr aparecerá no seu console.

    
por 27.07.2015 / 01:30