O problema é bastante simples: considero útil ter a possibilidade deligar (e desligar)a saída de algum programa em execução em cada momento que preciso. Para ser mais preciso, quero estar livre para redirecionar sua saída padrão (e erro) do shell atual para outro, para /dev/null
um arquivo ou de volta ao shell original.
Procuro algo direto (e seguro) que aproveite o fato de saberantecipadamenteque vou ligar e desligar as saídas. Eu posto uma resposta também.
Abaixo minha primeira tentativa. Suponhamos que eu trabalhe no shell número 35.
$ who am I # the command line to ask where am I
myuser pts/35 ... # The answer
Minha tentativa começa com um link simbólico para esse terminal
ln -s /dev/pts/35 MyOutput # The command to link
A ideia é lançar o programa com o redirecionamento definido para esse link
./Execute_program > MyOutput
Funciona, redireciona a saída para o meu terminal, mas quando dou o comando para alterar o link,
ln -sf /dev/null MyOutput
o link muda,mas o redirecionamento não mudacomo eu esperava. Isso não muda para o processo em execução. Se eu lançar um novo programa da mesma forma, o redirecionamento segue a nova prescrição do link.
Se eu começar de novo e definir o link para /dev/null
a saída será suprimida conforme o esperado, mas novamente quando eu alterar o link o redirecionamento não muda.
Se eu fizer um link para um link, obtenho o mesmo resultado. O uso de hard link
não muda a situação.
Tristementeo shell expande a linha de comando no momento da inicialização.
Existe alguma possibilidade de fazer o trabalho de forma semelhante ou devo descobrir como comunicar ao processo (ou aos PPID) que o link foi alterado?
Notas:
Esta é uma questão da série "Como redirecionar a saída de um processo em execução?", mas não parte do ponto"Ops, lancei o programa e esqueci de redirecionar a saída. Agora quero fazer isso", mas do contrário: "Como posso lançar um programa com o objetivo explícito de redirecionar a saída para outro lugar posteriormente?".
Pretendo utilizar tal procedimento quando não for possível (ou conveniente) modificar o código fonte do programa.
EUlerque é possível disown
processar, usar screen
e transferir de uma tela para outra... ou usar um depurador, para interceptar o processo... Todas essas soluções poderiam funcionar com uma boa quantidade de experiência e esforço, mas algumas delas também apresentam uma percentagem de risco.
Responder1
Eu encontro uma solução via mkfifo
, que cria um pipe nomeado, ouFIFOs.
Simples como criar um link simbólico e é possível utilizar todos os redirecionamentos permitidos pelo shell.
mkfifo MyOutput
ls -l
dá
0 prw-r--r-- 1 My_username My_username 0 May 11 17:45 MyOut|
Posso iniciar o programa com redirecionamento para esse link
./Execute_program > MyOutput & cat MyOutput
e a saída começa a fluir no terminal.
Se eu pressionar ctrl+ cinterrompo o fluxo, mas não o processo em execução (tenho que usar algo parecido kill pid
ou kill %1
fazer).
Quando numa segunda vez eu pedir aoFIFOspara despejar no terminal (novamente com cat MyOutput
) ele começará a despejar a saída a partir desse momento.
Notas e avisos:
- Até que eu peça um despejo,
FIFOs
ele conterá toda a saída.
Como vou perguntar da primeira vez, serádescarregartodos. - Posso redirecionar (ou anexar) para outro arquivo
cat MyOutput >> NewRealFile
- Posso usar
cat MyOutput
de outro terminal também! - Aviso: Se eu pedir a 2 programas (ou instâncias) diferentes para redirecionar a saída para o mesmo,
FIFOs
o fluxo será mesclado (sema priorimaneira de distinguir de quais programas essa linha vem). - Aviso: Se eu perguntar 2 ou mais vezes (talvez de terminais diferentes), ele fornecerá uma linha para cada solicitação, dividindo a saída para o solicitante. Talvez haja uma solução alternativa segura ...
Responder2
Se entendi sua pergunta corretamente:
script 1>>~/out.fifo 2>>~/error.fifo
então para monitorar você pode fazer algo como:
watch cat ~/out.fifo
Você poderia usar arquivos reais em vez de Fifos
script 1>/tmp/$0-out 2>/tmp/$0-error
então tail -f eles, eles serão substituídos quando você executar os scripts novamente.
Eu prefiro o segundo método, ou apenas usar um multiplexador (ou seja, tela ou qualquer que seja a reencarnação popular desta semana)
screen -t "name" bash -c 'script'
então
screen -r
para "monitorar" e ctrl+ad para desanexar.
Certifique-se de fazer uma pausa no final do seu script se quiser ver a saída após sua execução.
Responder3
se eu fosse você, apenas redirecionaria a saída para um arquivo e, em seguida, seguiria esse arquivo quando quisesse ver a saída ... também você pode querer limitar o tamanho desse arquivo se achar que a saída será bastante longa, ou tenha o arquivo escrito na memória RAM em vez de no disco se você acha que a saída será bastante rápida, mas como fazer essas coisas é outra questão, não sei.