Bash

如何根據條件告訴 Bash 中的 echo/printf 吞下轉義碼?

  • November 20, 2013

我有一個以互動方式執行的 Bash 腳本並作為一項cron工作。當互動執行時,它會在終端上輸出彩色文本。但是,當在其中執行時,cron它沒有終端,因此我[1;31m在輸出中得到了很多類似的東西。

如果輸出設備不支持轉義碼,Bash 有沒有辦法告訴它吞下轉義碼?

這與如何檢查 bash 是否可以列印顏色有關,這是關於檢查條件的。echo但是,我希望在呼叫或保留顏色的雙重功能時盡可能少地進行更改,printf具體取決於輸出設備。

不完全是吞嚥,但您可以通過參數擴展將它們刪除:

str='Hello \e[31mc\e[32mo\e[33ml\e[34mo\e[35mr\e[m world'

# colorful output
echo -e "$str"

# colorless output    
echo -e "${str//\\e\[+([0-9;])m}"

上面的 inbash需要打開extglobshell 選項。( shopt -s extglob)

為了更容易使用,定義一個函式:

function ecco() { [ -t 1 ] && echo -e "$1" || echo -e "${1//\\e\[+([0-9;])m}"; }

然後你就叫它:

ecco 'Hello \e[31mc\e[32mo\e[33ml\e[34mo\e[35mr\e[m world'

要檢查它是否有效,只需重定向它的輸出,顏色就會消失:

ecco 'Hello \e[31mc\e[32mo\e[33ml\e[34mo\e[35mr\e[m world' | cat

檢查您是否正在列印到終端。這就是 GNUls和 GNU等程序grep在您告訴它們時所做的事情--color=auto

即使您要列印到終端,理論上它也可能無法理解變色的轉義序列。在實踐中,所有常見和最不常見的終端都理解這些序列:我見過的所有 X11 終端仿真器、screen、tmux、Linux 控制台、*BSD 控制台、PuTTY、rxvt、Console2、ConEmu、 …

normal=
green=
…
if [ -t 1 ]; then
 normal=$'\e[0m'
 green=$'\e32m'
 …
fi
…
echo "foobar ${green}OK${normal}"

該測試[ -t 1 ]用於標準輸出和[ -t 2 ]標準錯誤。

在不支持$'…'擴展的 shell 中,您可以生成一個可移植的轉義字元esc=$(echo _ | tr _ '\033')

引用自:https://unix.stackexchange.com/questions/101810