Linux 中为什么有些程序正常运行可以在标准输出中打印,用了重定向>或者管道|后,重定向文件及管道中无任何输入? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
varius
V2EX    程序员

Linux 中为什么有些程序正常运行可以在标准输出中打印,用了重定向>或者管道|后,重定向文件及管道中无任何输入?

  •  
  •   varius 2022-12-02 23:10:36 +08:00 2851 次点击
    这是一个创建于 1044 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题。
    有些程序直接运行 COMMAND ,就能在屏幕中打 log 。
    但是如果在后面加上> 或者 | xargs 后,文件或管道中不能收到任何数据。
    想请教一下各位 Bash 玩的比较六的大佬们,到底什么问题?
    22 条回复    2022-12-04 17:41:57 +08:00
    moen
        1
    moen  
       2022-12-02 23:17:20 +08:00
    可能你看到其实是输出到 stderr ,直接重定向当然是没有内容
    varius
        2
    varius  
    OP
       2022-12-02 23:18:01 +08:00
    @moen 这个问题我有考虑过,然后将 stderr 重定向到 stdout 中,但是也失效。很奇怪
    gam2046
        3
    gam2046  
       2022-12-02 23:23:56 +08:00
    有些程序指的是哪些,给几个例子看,让人上来就猜是不是有点困难。
    varius
        4
    varius  
    OP
       2022-12-02 23:28:29 +08:00
    @gam2046 比如 bazel
    conanforever22
        5
    conanforever22  
       2022-12-02 23:53:11 +08:00
    我之前遇到过这样的问题,不知道和你的情况是否类似
    ```sh
    cmd_write_to_stderr 2>&1 > foo.txt # > 在 2>&1 后边的话是重定向不成功的
    ```
    但是
    ```sh
    cmd_write_to_stderr > foo.txt 2>&1 # > 在 2>&1 前边的话是没问题的
    ```
    kirory
        6
    kirory  
       2022-12-02 23:55:48 +08:00
    因为没有用 stdout / stderr, 比如 sudo 的输入用的都不是这些,而是直接读写终端
    kirory
        7
    kirory  
       2022-12-02 23:58:55 +08:00   2
    比如这些命令,对应的设备可能不是 1 ,可以多试几个数字
    echo Hello > /dev/pts/1
    cat < /dev/pts/1
    kirory
        8
    kirory  
       2022-12-03 00:04:54 +08:00
    @kirory 改进一下,把重定向位置改成 $(tty)
    geelaw
        9
    geelaw  
       2022-12-03 00:08:17 +08:00 via iPhone   1
    因为程序可以选择查看自己的标准流是哪里并选择不同的行为。比如 git diff 在 stdout 接入 terminal 的时候默认使用转义序列显示彩色,但 stdout 接入文件时默认不用。
    varius
        10
    varius  
    OP
       2022-12-03 01:01:07 +08:00
    @conanforever22 有些类似
    varius
        11
    varius  
    OP
       2022-12-03 01:01:25 +08:00
    @kirory 谢谢老哥指教,我测试一下
    varius
        12
    varius  
    OP
       2022-12-03 01:01:54 +08:00
    @geelaw 的确是的。而且现在有些 log 框架也会有类似的情况
    varius
        13
    varius  
    OP
       2022-12-03 01:02:54 +08:00
    @kirory 再请教下老哥,如果是直接读写终端的话,按道理不会出现用了管道或者重定向之后屏幕不输出的情况吧。
    luvjoey1996
        14
    luvjoey1996  
       2022-12-03 01:09:40 +08:00 via Android
    @conanforever22 参考一下 shellcheck
    bigdoing
        15
    bigdoing  
       2022-12-03 01:11:36 +08:00 via iPhone
    还是让高手来回答你们
    程序判断输出是 tty 的时候,按照行缓冲输出,有了新一行,就写
    如果是 pipe 的话,就会攒着,到一大块的时候,再写
    这种一般有参数控制,比如 grep ,就有一个参数控制
    varius
        16
    varius  
    OP
       2022-12-03 01:20:42 +08:00
    @bigdoing 请教一下,在这种情况如何可以强迫前面的有一行输出一行呢?
    jasonyang9
        17
    jasonyang9  
       2022-12-03 07:54:48 +08:00
    aloxaf
        18
    aloxaf  
       2022-12-03 08:39:06 +08:00
    @varius
    在伪终端里运行它们即可,zsh 用户的而话可以直接用 zpty 命令:
    https://github.com/lilydjwg/dotzsh/blob/master/zshrc#LL561-L561C7
    7RTDKSAK
        19
    7RTDKSAK  
       2022-12-03 15:31:00 +08:00   1
    @conanforever22

    因为重定向是有序地(至少在 BASH 中是有序地,其它 SHELL 我不了解)

    第一种写法:
    第一阶段:文件描述符 1 和 2 都指向屏幕(姑且说成"屏幕",方便理解),你把串流 2 重定向到了串流 1,而串流 1 又指向了屏幕,所以最终效果就是串流 2 指向了屏幕(虽然它原来也指向屏幕),串流 1 没有变化依旧指向屏幕
    第二阶段:在第一阶段(或者说在以前所有重定向阶段)基础上,串流 1 重定向到了文件(所以在屏幕上看不到了),串流 2 没有变化依旧指向屏幕
    所以最终效果就是你所说得"重定向不成功"

    第二种写法:
    略,言之有理即可(滑稽)

    另外,推荐&>file 这种写法,一次性把文件描述符 1 和 2 同时重定向到文件
    JohnBull
        20
    JohnBull  
       2022-12-03 17:32:42 +08:00
    不可能的

    肯定是太着急了,数据还在 buffer 里没刷出来呢,你就去看输出文件,发现是空的,就 sigint 了……
    varius
        21
    varius  
    OP
       2022-12-04 17:41:28 +08:00
    @jasonyang9 谢谢老哥指教
    varius
        22
    varius  
    OP
       2022-12-04 17:41:57 +08:00
    @aloxaf 谢谢老哥的提示,这是一个新思路,我去查一下 bash 里面有没有类似的实现
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     943 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 22:47 PVG 06:47 LAX 15:47 JFK 18:47
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86