Simule STDIN vazio para o comando desvinculado

3

Eu quero desanexar o comando com 'command &' no final, ou com 'nohup command &', mas ele pára logo depois de destacá-lo.

o comando é pouco específico, se ele recebe eof na entrada, ele quebra assim / dev / null como entrada levará ao fim e a solução que normalmente funciona:

$ command < /dev/null > /dev/null 2>&1 &

não está funcionando ...

existe outro dispositivo em unix / linux, que pode substituir / dev / null e se comportar como uma entrada vazia, mas não enviando eof.

(a propósito, o comando é muito útil emcast ferramenta multicasting, eu posso tentar remendar minha auto, ou encontrar versão corrigida para este fim ... mas parece que o problema pode ser resolvido fora)

Estou adicionando este EDIT para tornar minha pergunta mais clara. Eu fiz este programa C de 2 linhas que funciona perfeitamente: o nome do programa é "doação"

#include <unistd.h>
int main() {  while (1)  { sleep(10); } return 0; }

e é o que estou procurando, algum dispositivo / programa, que não faz nada, mas deixa seu stdout aberto. Ambos ("command & ... disown" e "nohup command &") funcionam.

$ donothing | mycommand >/dev/null & 
$ disown %1

funciona bem, então agora a questão é apenas: que dispositivo / programa unix se comporta como minha 'doação'.

    
por Asain Kujovic 17.03.2013 / 20:00

2 respostas

7

Para que seu comando detecte eof , ele precisa ler stdin. Então, presumivelmente, está esperando alguma entrada. Então, parece que o que você precisa não é uma entrada vazia ( /dev/null é exatamente para isso), mas a entrada que nunca chega.

Pode ser simulado com um tubo onde ninguém nunca vai escrever do outro lado como:

sleep 999999999 | the-command

Ou para evitar a necessidade de executar esse comando sleep extra, isso pode ser feito com um pipe nomeado:

fifo=$(mktemp -u) &&
  mkfifo "$fifo" &&
  (rm "$fifo" && the-command <&3 3<&- &) 3<> "$fifo"

Aqui, usando um descritor de arquivo intermediário para contornar o fato de que o shell conecta stdin a /dev/null implicitamente quando você inicia um comando com & (a menos que você adicione um redirecionamento stdin explícito como nosso <&3 aqui). / p>

No Linux (e provavelmente no Linux apenas), você também pode fazer:

the-command < /dev/fd/1 3>&1 > /dev/null | :

/dev/fd/1 onde o fd 1 está conectado a um pipe, no Linux, se comporta como um pipe nomeado. Isto é, quando você o abre no modo de leitura, você obtém o final da leitura do pipe.

Assim, acima, o fd 0 será conectado à extremidade de leitura de um canal cuja outra extremidade está no fd 3 de the-command . Porque the-command não vai escrever nada no seu fd 3, qualquer read tentativa em fd 0 irá bloquear (ou uma leitura sem bloqueio retornará com não há nada para ler ainda , ou um select / poll retornará nada para ler como the-command provavelmente está fazendo, se estiver fazendo qualquer outra coisa além de esperar por entradas que nunca aparecem.

    
por 17.03.2013 / 21:38
1

Você precisa usar o comando disown . Isso liberará o STDIN / STDOUT do shell atual no qual você está executando esses comandos.

% disown -a

-ou -

% sleep 100 &
[1] 7987
% disown %1

Veja a página do bash man para mais detalhes.

disown [-ar] [-h] [jobspec ...] Without options, each jobspec is removed from the table of active jobs. If the -h option is given, each jobspec is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If no jobspec is present, and neither the -a nor the -r option is supplied, the current job is used. If no jobspec is supplied, the -a option means to remove or mark all jobs; the -r option without a jobspec argument restricts operation to running jobs. The return value is 0 unless a jobspec does not specify a valid job.

    
por 17.03.2013 / 20:35

Tags