Help Evitando Buffer com Redirecionamento de Saída

1

Estou tentando escrever algumas funções que posso utilizar em meus scripts para marcar essencialmente todas as saídas como Erro vs saída padrão, lançar carimbos de data / hora e também incluir o nome da função da saída. Eu tenho tudo isso funcionando, exceto por problemas de buffer. Minha saída, essencialmente, não está em ordem cronológica.

Eu tentei combinações de unbuffer, sync, stdbuf, etc, mas não consigo fazê-lo funcionar. Qualquer ajuda ou explicação sobre por que especificamente isso está falhando para mim seria apreciada. Além disso, qualquer dica sobre uma execução mais simples disso seria ótima. Até agora, para obter o nome da minha função, tenho que reconfigurar meu redirecionamento em todas as chamadas de função.

#!/bin/bash

function stdOutput
{
    typeset strLogFile=$1; shift
    typeset strLogID=$1; shift
    while IFS='' read -r strInput
    do
        echo "$(eval echo ${strLogID})${strInput}" && echo "$(eval echo ${strLogID})${strInput}" >> ${strLogFile}
    done
}

function errOutput
{
    typeset strLogFile=$1; shift
    typeset strLogID=$1; shift
    while IFS='' read -r strInput
    do
        >&2 echo "$(eval echo ${strLogID})${strInput}" && echo "$(eval echo ${strLogID})${strInput}" >> ${strLogFile}
    done
}

function main
{
    stdLogID="\<STD\>!"'$'"(date +\"%Y-%m-%d!%H:%M:%S\")!"
    errLogID="\<ERR\>!"'$'"(date +\"%Y-%m-%d!%H:%M:%S\")!"
    logFile=/tmp/out.log
    > $logFile

    exec 3>&1 1> >(stdOutput ${logFile} "${stdLogID}${FUNCNAME[0]}!")
    exec 4>&2 2> >(errOutput ${logFile} "${errLogID}${FUNCNAME[0]}!")

    >&2 echo "Line1"
    echo "Line2"
    >&2 echo "Line3"
    echo "Line4"
    >&2 echo "Line5"
    echo "Line6"
    >&2 echo "Line7"
    echo "Line8"
    >&2 echo "Line9"
    echo "Line10"

    exec 1>&3 3>&-
    exec 2>&4 4>&-
}
main
sync
exit

O que eu espero obter como resultado desse script. Todas as outras linhas são ERR, em seguida, STD marcadas e os números de linha na ordem 1-10.

<ERR>!2016-08-01!14:06:15!main!Line1
<STD>!2016-08-01!14:06:15!main!Line2
<ERR>!2016-08-01!14:06:15!main!Line3
<STD>!2016-08-01!14:06:15!main!Line4
<ERR>!2016-08-01!14:06:15!main!Line5
<STD>!2016-08-01!14:06:15!main!Line6
<ERR>!2016-08-01!14:06:15!main!Line7
<STD>!2016-08-01!14:06:15!main!Line8
<ERR>!2016-08-01!14:06:15!main!Line9
<STD>!2016-08-01!14:06:15!main!Line10

Exemplo do tipo de saída que normalmente recebo. Números de linha fora de ordem devido ao buffer.

<ERR>!2016-08-01!14:06:15!main!Line1
<STD>!2016-08-01!14:06:15!main!Line2
<STD>!2016-08-01!14:06:15!main!Line4
<ERR>!2016-08-01!14:06:15!main!Line3
<STD>!2016-08-01!14:06:15!main!Line6
<ERR>!2016-08-01!14:06:15!main!Line5
<STD>!2016-08-01!14:06:15!main!Line8
<ERR>!2016-08-01!14:06:15!main!Line7
<STD>!2016-08-01!14:06:15!main!Line10
<ERR>!2016-08-01!14:06:15!main!Line9
    
por Ryan Flagler 01.08.2016 / 17:05

1 resposta

0

Meu problema era com os comandos "echo" FORA das minhas funções que lidavam com o redirecionamento. Todas as tentativas que fiz inicialmente estavam dentro da minha função. Para resolver isso, criei uma nova função "echo" que descompacta cada chamada de eco e uso "echo de comando" quando não quero utilizar a função. Isso obviamente só irá descomprimir os comandos de eco. Qualquer outro executável que produza texto também pode causar buffering.

#!/bin/bash

function stdOutput
{
    typeset strLogFile=$1; shift
    typeset strLogID=$1; shift
    while IFS='' read -r strInput
    do
    command echo "$(eval command echo ${strLogID})${strInput}" && command echo "$(eval command echo ${strLogID})${strInput}" >> ${strLogFile}
    done
}

function errOutput
{
    typeset strLogFile=$1; shift
    typeset strLogID=$1; shift
    while IFS='' read -r strInput
    do
    >&2 command echo "$(eval command echo ${strLogID})${strInput}" && command echo "$(eval command echo ${strLogID})${strInput}" >> ${strLogFile}
    done
}

function echo
{
    typeset strParameters=$@
    typeset strExecutable=$(which echo)
    unbuffer ${strExecutable} $@
}

function main
{
    stdLogID="\<STD\>!"'$'"(date +\"%Y-%m-%d!%H:%M:%S\")!"
    errLogID="\<ERR\>!"'$'"(date +\"%Y-%m-%d!%H:%M:%S\")!"
    logFile=/tmp/out.log
    > $logFile

    exec 3>&1 1> >(stdOutput ${logFile} "${stdLogID}"\$"{FUNCNAME[1]}!")
    exec 4>&2 2> >(errOutput ${logFile} "${errLogID}"\$"{FUNCNAME[1]}!")

    >&2 echo "Line1"
    echo "Line2"
    >&2 echo "Line3"
    echo "Line4"
    >&2 echo "Line5"
    echo "Line6"
    >&2 echo "Line7"
    echo "Line8"
    >&2 echo "Line9"
    echo "Line10"

    exec 1>&3 3>&-
    exec 2>&4 4>&-
}
main
sync
exit
    
por 02.08.2016 / 16:49