当涉及管道时,watch-color 不起作用?

当涉及管道时,watch-color 不起作用?

下面演示了如何watch使用颜色,但是当涉及管道时则不行。

$ touch test.txt
$ ls | grep --color test.txt
test.txt                                  # This IS colored output

$ watch --color 'ls | grep --color test.txt'
Every 2.0s: ls | grep --color test.txt         
test.txt                                  # This is NOT colored output

$ ls | grep --color test.txt
test.txt                                  # This IS colored output

$ watch --color 'ls --color'
Every 2.0s: ls --color
test.txt                                  # This IS colored output

我不明白为什么watch --color在 just 的情况下似乎有效,但在将ls的输出通过管道传输到 时却无效。lsgrep

答案1

分析

watch捕获所运行命令的输出。通常在交互式 shell 中,简单命令或管道中的最后一个命令会打印到终端。它watch打印到管道;watch从该管道读取、处理并写入其自己的标准输出(通常是终端)。

ls并且grep可以为其输出着色,每个工具都有自己的颜色。它们支持--color=auto选项。如果auto使用,ls或者grep如果 stdout 是终端,则会为其输出着色,但如果它是管道、常规文件等,则不会。

最重要的事情:ls --color似乎相当于ls --color=always,而grep --color似乎相当于grep --color=auto调查一下:

unalias ls    # because `ls --color=auto' seems to be a common alias
unalias grep  # just in case

# ls prints to terminal
ls                 # no color
ls --color=never   # no color
ls --color=always  # color
ls --color=auto    # color
ls --color         # color

# ls prints to pipe
ls                | cat  # no color
ls --color=never  | cat  # no color
ls --color=always | cat  # color
ls --color=auto   | cat  # no color
ls --color        | cat  # color                      <-- compare this

# grep prints to terminal
echo foo | grep                foo  # no color
echo foo | grep --color=never  foo  # no color
echo foo | grep --color=always foo  # color
echo foo | grep --color=auto   foo  # color
echo foo | grep --color        foo  # color

# grep prints to pipe
echo foo | grep                foo | cat  # no color
echo foo | grep --color=never  foo | cat  # no color
echo foo | grep --color=always foo | cat  # color
echo foo | grep --color=auto   foo | cat  # no color
echo foo | grep --color        foo | cat  # no color  <-- to this

解释

上述差异解释了您的结果:

  • $ ls | grep --color test.txt
    test.txt                                  # This IS colored output
    

    因为grep --color行为就像grep --color=auto并且 stdout 是终端。

  • $ watch --color 'ls | grep --color test.txt'
    Every 2.0s: ls | grep --color test.txt         
    test.txt                                  # This is NOT colored output
    

    因为grep --color行为类似于grep --color=auto并且其标准输出不是终端。注意:

    • ls本身在这里是无色的。
    • 涉及管道并不重要。你可以观察到类似的无色结果

      watch --color 'grep --color / /etc/fstab'
      

      并且命令中没有管道。

  • (您的第三个例子似乎与第一个例子重复。跳过。)

  • $ watch --color 'ls --color'
    Every 2.0s: ls --color
    test.txt                                  # This IS colored output
    

    因为ls --color行为像ls --color=always;它的输出不是终端并不重要。


解决方案

调用

watch --color 'ls | grep --color=always test.txt'

获取颜色grep

相关内容