Como posso saber se um programa está imprimindo para stderr ou stdout no terminal?

7

NOTA: aparece uma nova linha, mas od -c não a exibe.

O comando de status do meu player de música ( quodlibet --status | od -c ) tem três estados e estou tentando gravar uma condicional com base nessa saída. As saídas desse comando são assim (podem diferir dependendo da configuração).

  1. Eu acho que isso está imprimindo para stderr porque od -c não é exibido corretamente, mesmo que para os outros comandos.

    not-running
    0000000
    
  2. pausado

    0000000   p   a   u   s   e   d       P   a   n   e   d   B   r   o   w
    0000020   s   e   r       1   .   0   0   0       s   h   u   f   f   l
    0000040   e       o   n       0   .   2   2   8  \n
    0000053
    
  3. jogando

    0000000   p   l   a   y   i   n   g       P   a   n   e   d   B   r   o
    0000020   w   s   e   r       1   .   0   0   0       s   h   u   f   f
    0000040   l   e       o   n       0   .   2   3   2  \n
    0000054
    

Meu objetivo é remover tudo, exceto "não-executando", "pausado" ou "reproduzindo", e use isso em uma condição como esta:

#!/bin/bash

status=$(quodlibet --status | awk '{split($0,m," "); printf "%s",m[1]}' | tr -d '
echo -n "$(quodlibet --print-playing '<artist>: <title>' | cut -c1-45)"
0
not-running
0000000
70\n') if [ "$status" = "playing" ]; then quodlibet --print-playing '<artist>: <title>' | cut -c1-45 else echo -n "$status" fi

No caso em que o player não está sendo executado, isso sempre imprime uma nova linha no terminal depois de "não executar". Mesmo se eu fizer algo assim

not-running
0000000

Se eu canalizar essa saída para od -c , obtenho o mesmo

0000000   p   a   u   s   e   d       P   a   n   e   d   B   r   o   w
0000020   s   e   r       1   .   0   0   0       s   h   u   f   f   l
0000040   e       o   n       0   .   2   2   8  \n
0000053

que não está certo. A nova linha não aparece, mas é a sua no terminal.

Perguntas

  • O que está causando isso?
  • O comando imprime para erro padrão quando o programa não está em execução?
  • Como posso determinar isso?
por Michael A 06.12.2013 / 03:02

1 resposta

6

Algumas maneiras de abordar isso.

  1. mesclar fluxos

    Você poderia passar determinando a diferença todos juntos e simplesmente mesclar STDERR e STDOUT.

    Exemplo

    quodlibet --status 2>&1 | ...
    
  2. use grep

    Você poderia reduzir a saída usando -o & -E muda para grep .

    Exemplo

    $ echo "...blah not-running blah..." | grep -Eo "not-running|paused|playing"
    not-running
    
    $ echo "...blah paused blah..." | grep -Eo "not-running|paused|playing"
    paused
    
    $ echo "...blah playing blah..." | grep -Eo "not-running|paused|playing"
    playing
    

    Isso cortará tudo, exceto as strings que correspondem ao argumento regex para grep .

  3. determine o tipo do fluxo

    Você pode usar a opção -t para determinar o tipo de fluxo do descritor de arquivo.

    trecho da página man do Bash

    -t fd True if file descriptor fd is open and refers to a terminal.

    where fd is one of:

    0: stdin
    1: stdout
    2: stderr

    Exemplo

    Isso detecta se a saída está vindo do STDOUT.

    $ if [ -t 1 ]; then echo "from STDOUT"; fi
    from STDOUT
    

    Retorna "de STDOUT", pois a saída está chegando enquanto:

    $ (if [ -t 1 ]; then echo "from STDOUT"; fi) | cat
    

    Não retorna nada, pois a saída está sendo direcionada para cat .

por 06.12.2013 / 03:35