tail
não bloqueia
Como sempre: para tudo, existe uma resposta curta, fácil de entender, fácil de seguir e completamente errada. Aqui se tail -f /dev/null
enquadra nesta categoria;)
Se você olhar com strace tail -f /dev/null
atenção, notará que esta solução está longe de ser bloqueada! Provavelmente é ainda pior do que a sleep
solução em questão, pois utiliza (no Linux) recursos preciosos como o inotify
sistema. Também outros processos que escrevem para /dev/null
fazer tail
loop. (No meu Ubuntu64 16.10, isso adiciona vários 10 syscalls por segundo em um sistema já ocupado.)
A pergunta era para um comando de bloqueio
Infelizmente, não existe tal coisa ..
Leia: Não conheço nenhuma maneira de arquivar isso diretamente no shell.
Tudo (par sleep infinity
) pode ser interrompido por algum sinal. Portanto, se você quiser ter certeza de que ele não retorna excepcionalmente, ele deve ser executado em um loop, como você já fez para o seu sleep
. Observe que (no Linux) /bin/sleep
aparentemente tem limite de 24 dias (veja strace sleep infinity
), portanto, o melhor que você pode fazer provavelmente é:
while :; do sleep 2073600; done
(Observe que acredito em sleep
loops internamente para valores mais altos que 24 dias, mas isso significa: não está bloqueando, está fazendo um loop muito lento. Então, por que não mover esse loop para fora?)
.. mas você pode chegar bem perto com um nome fifo
Você pode criar algo que realmente bloqueie, desde que não haja sinais enviados ao processo. Seguintes usos bash 4
, 2 PIDs e 1 fifo
:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
Você pode verificar se isso realmente bloqueia strace
se você gosta:
strace -ff bash -c '..see above..'
Como isso foi construído
read
bloqueia se não houver dados de entrada (consulte outras respostas). No entanto, o tty
(aka. stdin
) Geralmente não é uma boa fonte, pois é fechado quando o usuário efetua logout. Também pode roubar alguma entrada do tty
. Não é legal.
Para fazer o read
bloco, precisamos esperar por algo como um fifo
que nunca retorne nada. Em bash 4
há um comando que pode exatamente nos fornecer tal um fifo
: coproc
. Se também esperarmos o bloqueio read
(que é o nosso coproc
), estamos prontos. Infelizmente, isso precisa manter abertos dois PIDs e um fifo
.
Variante com um nome fifo
Se você não se incomodar em usar um nome fifo
, faça o seguinte:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
Não usar um loop na leitura é um pouco desleixado, mas você pode reutilizá-lo fifo
quantas vezes quiser e read
usar o terminat s touch "$HOME/.pause.fifo"
(se houver mais de uma única leitura aguardando, todos serão encerrados de uma só vez).
Ou use o pause()
syscall do Linux
Para o bloqueio infinito, há uma chamada do kernel do Linux, chamada pause()
, que faz o que queremos: Espere para sempre (até que um sinal chegue). No entanto, ainda não existe um programa de espaço para usuário.
C
Criar esse programa é fácil. Aqui está um trecho para criar um programa de Linux muito pequena chamada pause
que faz uma pausa por tempo indeterminado (necessidades diet
, gcc
etc.):
printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause
python
Se você não deseja compilar algo, mas já python
instalou, você pode usá-lo no Linux:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Nota: Use exec python -c ...
para substituir o shell atual, isso libera um PID. A solução também pode ser aprimorada com algum redirecionamento de E / S, liberando FDs não utilizados. Isso depende de você.)
Como isso funciona (eu acho): ctypes.CDLL(None)
carrega a biblioteca C padrão e executa a pause()
função nela dentro de algum loop adicional. Menos eficiente que a versão C, mas funciona.
Minha recomendação para você:
Fique no sono em loop. É fácil de entender, muito portátil e bloqueia a maior parte do tempo.