AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 748078
Accepted
furynerd
furynerd
Asked: 2023-06-06 15:59:54 +0800 CST2023-06-06 15:59:54 +0800 CST 2023-06-06 15:59:54 +0800 CST

recuperar o redirecionamento de saída std para /dev/null

  • 772

existe uma maneira de recuperar std redirecionado para /dev/null? Eu tentei tail -f /proc/{PID}/fd/1, parece que só funciona, exceto redireciona para /dev/null.

ou seja

tail -f /proc/${cmd_pid}/fd/1

funciona cmd > log.txtmas nãocmd > /dev/null

------------atualizar------------

na verdade, meu problema será log.txtmuito grande se sempre registrar o stdout. seria melhor se eu pudesse controlar quando registrar ou interromper o registro (sem interromper o cmdprocesso em si).

então se é possível redirecionar o stdout para algum tmpsistema de arquivos que não ocupa nenhum recurso, e quando eu precisar posso recuperar o stdout?

process
  • 3 3 respostas
  • 65 Views

3 respostas

  • Voted
  1. symcbean
    2023-06-06T16:35:24+08:002023-06-06T16:35:24+08:00

    Não, você não pode alterar o identificador do arquivo.

    então se é possível redirecionar o stdout para algum sistema de arquivos tmp que não ocupa nenhum recurso, e quando eu precisar posso recuperar o stdout?

    Não, você não pode armazenar os dados sem armazená-los em algum lugar .

    Alguém provavelmente escreveu um buffer circular - o que permitiria que você visse (digamos) os últimos 100k de dados. Alternativamente, se o programa estiver rodando normalmente sem comando, você pode enviar a saída para a tela e executá-la via screen.

    • 0
  2. muru
    2023-06-06T17:09:18+08:002023-06-06T17:09:18+08:00

    quando não estou recuperando, o stdout pode ser descartado, quando começo a recuperar, o stdout pode ser redirecionado para um arquivo de log.

    Isso pode ser feito canalizando a saída para um script de shell, como o seguinte:

    #! /bin/sh
    # a-script.sh
    while IFS= read -d input
    do
      printf "%s\n" input >> /some/file
    done 
    

    Observe que o redirecionamento é feito dentro do loop, especificamente para que o arquivo de saída seja aberto novamente a cada iteração. Então, para começar:

    ln -s /dev/null /some/file
    cmd | a-script.sh
    

    Então, quando você quiser os logs:

    ln -sf /some/log/file /some/file
    

    E a próxima iteração do loop começará a gravar /some/log/fileem vez de em /dev/null.

    Se o seu comando registra muito, isso pode resultar em uma penalidade severa de desempenho.

    • 0
  3. Best Answer
    Stéphane Chazelas
    2023-06-06T17:16:43+08:002023-06-06T17:16:43+08:00

    Quando você faz cmd > /dev/null, o shell, em um novo processo filho, abre fd 1 /dev/nulle executa cmd.

    cmdfaz alguns write(1, "output"...)para gravar dados em stdout (ou possivelmente em outras chamadas de sistema de gravação, como send, sendmsgou pwrite), independentemente do que esse fd está aberto.

    No Linux, /proc/$pid_of_cmd/fd/1será apenas um link simbólico mágico para /dev/null, o arquivo fd 1 está aberto, então tail -f thatserá o mesmo que tail -f /dev/null.

    Você pode interceptar essas write()chamadas do sistema stracee decodificar o resultado:

    strace -zqqs99999 -xxa0 -o /dev/stdout -e write -p "$pid" |
       perl -ne 'print chr(hex($_)) for /\\x(..)/g'
    

    Ou:

    strace -zqqs99999 -xxa0 -o /dev/stdout -e write -p "$pid" |
       perl -ne 'if (/^write\(1,/) {print chr(hex($_)) for /\\x(..)/g}'
    

    Para apenas os write()s para stdout (fd 1). Ou:

    strace -yzqqs99999 -xxa0 -o /dev/stdout -e write -p "$pid" |
       perl -ne 'if (/^\Qwrite(1<\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c>,\E "(.*)"/) {
         print chr(hex($_)) for $1 =~ /\\x(..)/g}'
    

    Somente para write()s para stdout (fd 1) e somente quando stdout estiver aberto em /dev/null.

    Observe que, se você redirecionar a saída de perlpara algo diferente de um dispositivo tty, ele começará a armazenar em buffer por blocos em vez de por linha, portanto, você verá apenas a saída em lotes de alguns kibibytes. Você pode desativar esse buffer definindo a $|variável como 1:

    strace -zqqs99999 -xxa0 -o /dev/stdout -e write -p "$pid" |
       perl -ne 'BEGIN{$| = 1}
                 print chr(hex($_)) for /\\x(..)/g' > file
    

    Como alternativa, em vez de fazer cmd > /dev/null, faça cmd | cat > /dev/null.

    Então cmdo stdout do 's será um pipe, e no Linux, /proc/$pid_of_cmd/fd/1se comportará como um pipe nomeado, então se você fizer:

    kill -s STOP "$pid_of_cat"
    cat "/proc/$pid_of_cmd/fd/1"
    

    Na verdade, você redirecionará o pipe para seu novo catcomando.

    Se você terminar aquele novo cat, você vai querer retomar o outro ( kill -s CONT "$pid_of_cat") para reabrir a torneira /dev/nullnaquele cano.

    Para realmente alterar para onde vai o stdout do processo, você pode anexar um depurador:

    gdb --pid "$pid_of_cmd"
    

    Então no gdb:

    call close(1)
    p open("/path/to/some/file", 0x241, 0600)
    detach
    

    (0x241 para O_WRONLY|O_TRUNC|O_CREAT)

    Verifique se open()retorna fd 1. Caso contrário, você pode precisar de alguma chamada para dup2()e um arquivo close().

    • 0

relate perguntas

  • Como substituir os IDs de usuário e IDs de grupo por nomes em vez de números em "ps"?

  • Como obter os IDs dos grupos suplementares de um processo?

  • O que `/proc/irq/.../spurious` contém?

  • Um processo pai pode alterar o ambiente de seu filho?

  • Como 'ejetar' obtém processos para fechar identificadores de arquivo?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve