Bash
如何根據條件告訴 Bash 中的 echo/printf 吞下轉義碼?
我有一個以互動方式執行的 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}"
上面的 in
bash
需要打開extglob
shell 選項。(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
檢查您是否正在列印到終端。這就是 GNU
ls
和 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')