Por que o grep está retornando linhas não correspondentes quando não redireciono stderr para stdout?

Por que o grep está retornando linhas não correspondentes quando não redireciono stderr para stdout?

O script que uso está retornando esta saída:

(source /Thetra/Commun/env_ora.sh >/dev/null; sh aclenv/arun)

geIlgif0t1 -DVORACLE
geIlgif0t1
prg_25900:
ACOMP=X
geAhadlAd1 -DVORACLE
geAhadlAd1
prg_25948:
ACOMP=A
syCcgge0t1 -DVORACLE
syCcgge0t1
prg_26023:
ACOMP=S2
syVcalq0t1 -DVORACLE
syVcalq0t1
prg_26071:
ACOMP=Y
syVvali0t1 -DVORACLE
syVvali0t1
prg_26119:
ACOMP=Y
syAedit0t1 -DVORACLE
syAedit0t1
prg_26167:
(1312) DBMS WARNING: Column not found in table. (-11238)
  RETURN (-6)
    END
 END
    END
    IF cm_para_f2('VDEF','abQtip_0n1','unicite',syAedit0t1:$v_unicite)<>0
     OR null_convert$(syAedit0t1:$v_unicite,'R') <> 'F' THEN SET syAedit0t1:$v_unicite TO 'R'
    SET $v_tips_mrgl TO 'S'
    SET $v_rfbt_iban, $v_rfbt_intitule, $v_orga_creancier, $v_orga_tip_adr1, $v_orga_tip_adr2,
        $v_orga_tip_adr3, $v_code_docu, $v_tips_centre, $v_code_etab, $v_orga_tip_emetteur,
 $v_orga_emetteur, $v_rfbt_compte, $v_orga_banque, $v_rfbt_emetteur TO
    SELECT rfbt_iban, rfbt_intitule, orga_creancier, orga_tip_adr1, orga_tip_adr2, orga_tip_adr3
ACOMP=N
syAvali0t1 -DVORACLE
syAvali0t1
prg_26215:
(2751) DBMS WARNING: Column not found in table. (-11238)
 + to_string_using$(str_to_val$(substr$(clip_str$(to_string$($f_imme_no)),1,4)),'&&&&')
        + to_string_using$(str_to_val$(substr$(clip_str$(to_string$($f_sepa_propriete_no)),1,5)),'&&&&&')
    IF syAvali0t1:$v_unicite ='R' THEN
 SET $v_sepa_rum3 TO $v_sepa_rum3 + substr$(to_string_using$(syAvali0t1:$v_ordr_direct,'&&&&&&&&&'),7,9)
    ELSE
ACOMP=N
syAcalc0t1 -DVORACLE
syAcalc0t1
prg_26263:
ACOMP=N
syAcalc0t2 -DVORACLE
syAcalc0t2
prg_26311:
ACOMP=N
syAcalc0t3 -DVORACLE
syAcalc0t3
prg_26359:
ACOMP=N

Para verificar se há erros eu uso o seguinte comando:

(source env_ora.sh >/dev/null; sh aclenv/arun) | egrep '^ACOMP=$'

Saída:

(1312) DBMS WARNING: Column not found in table. (-11238)
  RETURN (-6)
    END
 END
    END
    IF cm_para_f2('VDEF','abQtip_0n1','unicite',syAedit0t1:$v_unicite)<>0
     OR null_convert$(syAedit0t1:$v_unicite,'R') <> 'F' THEN SET syAedit0t1:$v_unicite TO 'R'
    SET $v_tips_mrgl TO 'S'
    SET $v_rfbt_iban, $v_rfbt_intitule, $v_orga_creancier, $v_orga_tip_adr1, $v_orga_tip_adr2,
        $v_orga_tip_adr3, $v_code_docu, $v_tips_centre, $v_code_etab, $v_orga_tip_emetteur,
 $v_orga_emetteur, $v_rfbt_compte, $v_orga_banque, $v_rfbt_emetteur TO
    SELECT rfbt_iban, rfbt_intitule, orga_creancier, orga_tip_adr1, orga_tip_adr2, orga_tip_adr3
(2751) DBMS WARNING: Column not found in table. (-11238)
 + to_string_using$(str_to_val$(substr$(clip_str$(to_string$($f_imme_no)),1,4)),'&&&&')
        + to_string_using$(str_to_val$(substr$(clip_str$(to_string$($f_sepa_propriete_no)),1,5)),'&&&&&')
    IF syAvali0t1:$v_unicite ='R' THEN
 SET $v_sepa_rum3 TO $v_sepa_rum3 + substr$(to_string_using$(syAvali0t1:$v_ordr_direct,'&&&&&&&&&'),7,9)
    ELSE

Podemos ver que grep está retornando linhas não correspondentes.

Quando redireciono o stderr para stdout com este comando:

(source /Thetra/Commun/env_ora.sh >/dev/null; sh /Thetra/Oracle/transfert/P2016.H.1/aclenv/arun) 2>&1 | egrep '^ACOMP=$'

Como esperado, a saída é nula.

Por que o grep está retornando linhas não correspondentes quando o stderr não é redirecionado?

Responder1

Se você executar este comando, obterá dois arquivos, um chamado stdoute outro chamado stderr, contendo a saída parasaída padrãoe a saída parastderr, respectivamente:

(source env_ora.sh >/dev/null; sh aclenv/arun) >stdout 2>stderr

Seu grepcomando vê apenas dados enviados parasaída padrão. Ele nem vê os dados que aqui estão gravadosstderr.

Tomando uma variação do seu exemplo em um comentário subsequente, você verá que apenassaída padrãopassa pelo tubo para ser processado por sed:

( echo "stdout"; echo "stderr" >&2 ) | sed 's/std/STD/'
stderr
STDout

A outra linha de saída é escrita diretamente nostderrcanal, que por padrão está conectado ao seu terminal.

Em resumo: um pipeline anexasaída padrãode um comando parastdindo próximo. OstderrO canal é anexado ao seu terminal para que mensagens de erro (ou atualizações de status) possam ser gravadas nele sem afetar o fluxo de dados reais.

informação relacionada