当我不将 stderr 重定向到 stdout 时,为什么 grep 返回不匹配的行?

当我不将 stderr 重定向到 stdout 时,为什么 grep 返回不匹配的行?

我使用的脚本实际上返回以下输出:

(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

为了检查错误,我使用以下命令:

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

输出:

(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

我们可以看到 grep 返回不匹配的行。

当我使用以下命令将 stderr 重定向到 stdout 时:

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

正如预期的那样,输出为空。

当 stderr 未重定向时,为什么 grep 返回不匹配的行?

答案1

如果运行此命令,您将获得两个文件,一个名为stdout,一个名为stderr,其中包含输出标准输出和输出到标准错误, 分别:

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

您的grep命令只能看到发送到的数据标准输出。它甚至看不到这里写入的数据标准错误

在后续评论中采用您的示例的变体,您只会看到标准输出通过管道进行处理sed

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

另一行输出直接写入标准错误频道,默认情况下连接到您的终端。

总而言之:管道连接标准输出从一个命令到标准输入下一个。这标准错误通道连接到您的终端,以便可以在其中写入错误消息(或状态更新),而不会影响实际数据流。

相关内容