E sobre isso:
foo='{ { cat 1>&3; kill 0; } | { sleep 2; kill 0; } } 3>&1'
Ou seja: execute o comando de produção de saída e sleep
no mesmo grupo de processos, um grupo de processos apenas para eles. Qualquer comando que retorne primeiro mata todo o grupo de processos.
Alguém se perguntaria: Sim, o tubo não é usado; é ignorado usando os redirecionamentos. O único propósito é fazer com que o shell execute os dois processos no mesmo grupo de processos.
Como Gilles apontou em seu comentário, isso não funcionará em um shell script porque o processo do script seria morto junto com os dois subprocessos.
Uma forma de forçar um comando a ser executado em um grupo de processos separado é iniciar um novo shell interativo:
#!/bin/sh
foo='sh -ic '{ cat 1>&3; kill 0; } | { sleep 2; kill 0; }' 3>&1 2>/dev/null'
[ -n "$foo" ] && echo got: "$foo" || echo timeouted
Mas pode haver ressalvas com isso (por exemplo, quando stdin não é um tty?). O redirecionamento stderr está lá para se livrar da mensagem "Terminado" quando o shell interativo é eliminado.
Testado com zsh
, bash
e dash
. Mas e os velhos?
B98 sugere a seguinte mudança, trabalhando no Mac OS X, com o GNU bash 3.2.57, ou Linux com traço:
foo='sh -ic 'exec 3>&1 2>/dev/null; { cat 1>&3; kill 0; } | { sleep 2; kill 0; }''
-
1. diferente de setsid
, que parece não ser padrão.