Bashでecho / printfに条件付きでエスケープコードを飲み込むように指示する方法は?

Bashでecho / printfに条件付きでエスケープコードを飲み込むように指示する方法は?

タスクとして対話的に実行されるBashスクリプトがありますcron。インタラクティブに実行すると、端末にカラーテキストが出力されます。しかし、実行してcronみると端末がないので、[1;31m出力でも同様の結果がたくさん出てきます。

出力デバイスがエスケープコードをサポートしていない場合、Bashにエスケープコードを飲み込むように指示する方法はありますか?

これは以下に関連しています。Bashが色を印刷できるかどうかを確認する方法状態を確認することです。ただし、出力装置によって色の二重機能を維持しechoたり、両方を維持しながら呼び出すときにprintfできるだけ少ない変更をしたいと思います。

答え1

端末で印刷していることを確認してください。lsこれはGNUや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 ]標準エラーに関するものです。

拡張をサポートしていないシェルでは、$'…'次のように移植可能なエスケープ文字を生成できます。esc=$(echo _ | tr _ '\033')

答え2

まったく飲み込むわけではありませんが、パラメータ拡張で削除できます。

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}"

上記の場合は、シェルオプションをオンにする必要がありますbashextglob( 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

答え3

インタラクティブに実行されている場合は、スクリプトをチェックインする必要がありますか?

http://www.gnu.org/software/bash/manual/html_node/Is-this-Shell-Interactive_003f.html

引用符:

6.3.2 このシェルは対話型ですか?

起動スクリプトのBashがインタラクティブに実行されていることを確認するには、「-」特殊パラメータの値をテストします。シェルが対話型の場合、iが含まれます。たとえば、

case "$-" in
  *i*)   echo This shell is interactive ;;
   *)    echo This shell is not interactive ;;
esac

あるいは、起動スクリプトで変数PS1を確認することもできます。この変数は非対話型シェルで設定解除され、対話型シェルでは設定されます。したがって:

if [ -z "$PS1" ]; then
   echo This shell is not interactive
else
   echo This shell is interactive
fi

対話型の場合は「_escape_codes_」、そうでない場合は「」で変数セットを定義し、この変数を使用してスクリプトの出力色を指定します(対話型環境ではエスケープコードがあり、非対話型環境では独立して追加されます)。本文)。

前任者:

case "$-" in
  *i*)    _bold_="$(printf '\033[1m')"
          _norm_="$(printf '\033[0m')"
          ;;
  *)      _bold_=""
          _norm_=""
          ;;
esac
echo "this ${_bold_}text${_norm_} is important"

関連情報