检测Shell脚本的输出流类型

16

我正在编写一个使用ANSI颜色字符的shell脚本。

示例:example.sh

#!/bin/tcsh
printf "\033[31m Success Color is awesome!\033[0m"

我的问题是在执行以下操作时:

$ ./example.sh > out
或者
$./example.sh | grep 

在文本中,ASCII码会与文本一起原样发送,这样会破坏输出并导致混乱。我想知道是否有一种方法可以检测这种情况,以便我可以针对此特殊情况禁用颜色。

我已经搜索了tcsh man页面和网络一段时间,但尚未能够找到任何特定于shell的内容。

虽然我们的组标准是tcsh,但我并没有受到限制。

在shell脚本内部,是否有可能检测输出是否被重定向或管道传输?


1
我们刚刚做了这个:https://dev59.com/UXNA5IYBdhLWcg3wjOzf - dmckee --- ex-moderator kitten
哈哈,他问我遇到问题的确切时间有点令人毛骨悚然。我现在才正式提出这个问题。 - Brian Gianforcaro
相关的一个问题:http://unix.stackexchange.com/q/9957/50602 - Palec
4个回答

13

请参考这个之前的SO问题, 它涵盖了bash。Tcsh使用filetest -t 1提供相同的功能,以查看标准输出是否为终端。如果是,则打印颜色内容,否则省略。以下是tcsh:

#!/bin/tcsh
if ( -t 1 ) then
        printf "\033[31m Success Color is awesome!\033[0m"
else
        printf "Plain Text is awesome!"
endif

csh 不是我的母语。对于最初的错误表示抱歉。 - dwc

7

在 bourne shell 脚本(sh、bask、ksh 等)中,您可以使用 -s 标志将标准输出提供给 tty 程序(Unix 中的标准程序),它会告诉您输入是否为 tty。将以下内容放入“check-tty”中:

    #! /bin/sh
    if tty -s <&1; then
      echo "Output is a tty"
    else
      echo "Output is not a tty"
    fi

然后尝试一下:

    % ./check-tty
    Output is a tty
    % ./check-tty | cat
    Output is not a tty

我不使用tcsh,但是一定有办法将标准输出重定向到tty的标准输入。如果没有,可以使用

    sh -c "tty -s <&1"

在您的tcsh脚本中,使用该测试命令并检查其退出状态即可完成。

sh -c "tty -s <&1" 当从另一个脚本中调用时,将始终返回非 tty。不过这是个好答案。 - Brian Gianforcaro
不会的(我刚测试过了)。 - Samuel Tardieu

3
检测输出流类型的问题在此问题中得到了解决:detect if shell script is running through a pipe
一旦确定正在与终端交互,您可以使用tput检索特定终端的正确转义代码-这将使代码更具可移植性。
下面是一个示例脚本(遗憾的是,它是用bash编写的,因为tcsh不是我的强项)。
#!/bin/bash

fg_red=
fg_green=
fg_yellow=
fg_blue=
fg_magenta=
fg_cyan=
fg_white=
bold=
reverse=
attr_end=

if [ -t 1 ]; then
    fg_red=$(tput setaf 1)
    fg_green=$(tput setaf 2)
    fg_yellow=$(tput setaf 3)
    fg_blue=$(tput setaf 4)
    fg_magenta=$(tput setaf 5)
    fg_cyan=$(tput setaf 6)
    fg_white=$(tput setaf 7)
    bold=$(tput bold)
    reverse=$(tput rev)
    underline=$(tput smul)
    attr_end=$(tput sgr0)
fi

echo "This is ${fg_red}red${attr_end}"
echo "This is ${fg_green}green${attr_end}"
echo "This is ${fg_yellow}yellow${attr_end}"
echo "This is ${fg_blue}blue${attr_end}"
echo "This is ${fg_magenta}magenta${attr_end}"
echo "This is ${fg_cyan}cyan${attr_end}"
echo "This is ${fg_white}white${attr_end}"
echo "This is ${bold}bold${attr_end}"
echo "This is ${reverse}reverse${attr_end}"
echo "This is ${underline}underline${attr_end}"

如需更多信息,请参阅“man tput”和“man terminfo”,其中有各种可供使用的转义代码。


-2
据我所知,无法确定您的 shell 脚本输出的最终目的地;您唯一能做的就是提供一个开关,允许在输出中抑制控制字符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接