Eu tenho um programa que produz informações úteis, stdout
mas também lê stdin
. Quero redirecionar sua saída padrão para um arquivo sem fornecer nada na entrada padrão. Até agora, tudo bem: eu posso fazer:
program > output
e não faça nada no tty.
No entanto, o problema é que quero fazer isso em segundo plano. Se eu fizer:
program > output &
o programa será suspenso ("suspenso (entrada tty)").
Se eu fizer:
program < /dev/null > output &
o programa termina imediatamente porque atinge EOF.
Parece que o que eu preciso é entrar em program
algo que não faz nada por um período indefinido de tempo e não lê stdin
. As seguintes abordagens funcionam:
while true; do sleep 100; done | program > output &
mkfifo fifo && cat fifo | program > output &
tail -f /dev/null | program > output &
Porém, tudo isso é muito feio. Látemser uma maneira elegante, usando utilitários Unix padrão, de "não fazer nada, indefinidamente" (parafraseando man true
). Como eu poderia conseguir isso? (Meus principais critérios de elegância aqui: sem arquivos temporários; sem espera ocupada ou ativações periódicas; sem utilitários exóticos; o mais curto possível.)
Responder1
Eu não acho que você vai ficar mais elegante do que o
tail -f /dev/null
que você já sugeriu (supondo que isso use o inotify internamente, não deve haver pesquisas ou ativações; portanto, além de ter uma aparência estranha, deve ser suficiente).
Você precisa de um utilitário que será executado indefinidamente, manterá seu stdout aberto, mas na verdade não gravará nada no stdout e não sairá quando seu stdin for fechado. Algo como yes
realmente grava no stdout. cat
sairá quando seu stdin for fechado (ou o que quer que você redirecione para ele estiver concluído). Acho sleep 1000000000d
que pode funcionar, mas tail
é claramente melhor. Minha caixa Debian tem um tailf
comando que encurta um pouco.
Tomando uma abordagem diferente, que tal executar o programa em screen
?
Responder2
sleep infinity
é a solução mais clara que conheço.
Você pode usar infinity
porque sleep
aceita um número de ponto flutuante*, que pode serdecimal,hexadecimal,infinidade, ouNaN, de acordo com man strtod
.
* Isso não faz parte do padrão POSIX, portanto não é tão portátil quanto o tail -f /dev/null
. No entanto, é suportado em GNU coreutils (Linux) e BSD (usado no Mac) (aparentemente não suportado em versões mais recentes do Mac - veja os comentários).
Responder3
sleep 2147483647 | program > output &
Sim, 2^31-1
é um número finito e não funcionapara sempre, mas eu lhe darei US$ 1.000 quando o sono finalmente acabar. (Dica: um de nós estará morto até lá.)
- sem arquivos temporários; verificar.
- sem espera ocupada ou despertares periódicos; verificar
- sem utilidades exóticas; verificar.
- o mais curto possível. Ok, poderia ser mais curto.
Responder4
Você pode criar um binário que faça exatamente isso com:
$ echo 'main(){pause();}'| gcc -Wno-all -xc - -o pause
Acho isso elegante porque a pause
chamada do sistema é literalmente a única chamada do sistema cujo único propósito é não fazer nada para sempre (ou até que um sinal interrompa o processo) sem esperar ocupado, fazendo isso como um efeito colateral de outra coisa ou sem informar o processo pai (os pais podem elegantemente não bloquear waitpid
seus filhos para serem interrompidos pelo sinal, e muitos (principalmente os shells) o fazem, embora seja um pouco mais difícil esperar que um filho seja bloqueado em uma chamada de sistema sem aumento de sinal) .