Redireciona stderr para um arquivo, mas cria somente se algum stderr acontecer? [duplicado]

2

Estou executando um comando como:

parallel --spreadstdin --line-buffered 'some_command 2> 'mktemp --tmpdir /tmp/stderr'' | do_something

O truque é que parallel cria muitos processos e todos recebem um arquivo stderr, a maioria dos quais é desinteressante porque está vazia. Como posso fazer com que meu shell gere um arquivo stderr somente se alguma saída de erro padrão realmente ocorrer?

    
por d33tah 03.10.2014 / 13:57

3 respostas

1

Tanto quanto sei, isso é impossível. O shell lê da direita para a esquerda, portanto, se 2> error existir. um arquivo error será criado. Eu não acho que haja alguma maneira de contornar isso.

Você pode fazer alguns truques complexos, como usar um pipe nomeado e testar sua saída, mas acho que não vale a pena. Em vez disso, eu usaria inotify como explicado em outra resposta ou criaria arquivos tmp e os copiaria para um local diferente se eles contiverem dados.

tmp=$(mktemp); command 2> "$tmp"; [ -s "$tmp" ] && cp "$tmp" /path/to/log/files
    
por 03.10.2014 / 16:03
0

parallel --spreadstdin --line-buffered 'some_command 2 \

mktemp --tmpdir /tmp/stderr' | do_something && if [test -s /tmp/stderr]; then; sleep .1; else; rm /tmp/stderr

  • Um-Liner para testar se o arquivo existe e o tamanho é maior que zero para TRUE; vazio se FALSE.

I.T. é sobre fazer algo que funcione. Pare de contar seus bits e bytes e crie um gatilho inotifywait na inicialização para verificar seus logs se estiverem vazios, registrar os resultados para a tabela de dados e limpar o log-in concluído; em seguida, programe uma interface da web que envia um e-mail quando as palavras-chave aparecem no seu registro de erros.

while:
  do
    inotifywait -e create /tmp/* && \
      if [ -s /tmp/stderr ]
        then
        ##put it in a datatable
        ##remove the log
      fi
  done

O iNotifyWait também pode monitorar o subsistema Kernel F / S para ver se um arquivo é alterado, se você estiver anexando. Caso contrário, modifique o código-fonte e recompile para evitar que o erro seja criado, modificando a seção try () catch () ou relatório de erros (a parte que imprime os códigos de erro na tela).

    
por 03.10.2014 / 14:29
0

É incrível o quão perto a resposta para essa outra pergunta sobre SO veio para responder a pergunta sem atingir a marca. Defina uma função de shell (ou escreva um script) assim:

save_err()
{
    # Check that "$1" is set and either complain/abort or generate a default.
    if read -r x
    then
        { printf "%s\n" "$x"; cat; } > "$1"
    fi
}

Em seguida, use como:

some_command 2> >( save_err $(mktemp --tmpdir /tmp/stderr) )

Advertências: Isso falhará se a saída do stderr for uma única linha não terminando com uma nova linha . Para corrigir isso, altere as entranhas da função para

    if read -r x
    then
        { printf "%s\n" "$x"; cat; } > "$1"
    elif [ "$x" != "" ]
    then
        printf "%s" "$x" > "$1"
    fi

Eu usei printf em vez de echo para proteger contra texto começando com um traço ou contendo barras invertidas. Pode haver problemas se a primeira linha da saída stderr contiver caracteres não-ASCII.

    
por 03.10.2014 / 19:03