メッセージをBashスクリプトで印刷していますが、メッセージの一部を色分けします。例えば、
#!/bin/bash
normal='\e[0m'
yellow='\e[33m'
cat <<- EOF
${yellow}Warning:${normal} This script repo is currently located in:
[ more messages... ]
EOF
しかし、ターミナル(gnome-terminal
内のtmux
)で実行すると、 ANSIエスケープ文字 が\
形式で出力されます。例えば、
\e[33mWarning\e[0m This scr....
色付けしたい部分をヒアドキュメント外のprintf
コマンドに移動すると機能します。たとえば、これは動作します:
printf "${yellow}Warning:${normal}"
cat <<- EOF
This script repo is currently located in:
[ more messages... ]
EOF
man bash
から–ここのドキュメント:
Wordに対して、パラメーターおよび変数の展開、コマンド置換、算術展開、またはパス名展開は実行されません。 Word内の文字が引用符で囲まれている場合、区切り文字はWord、およびhere-documentの行は展開されません。 Wordが引用符で囲まれていない場合、ヒアドキュメントのすべての行は、パラメータ展開、コマンド置換、および算術展開の対象になります。後者の場合、文字シーケンス\ <newline>は無視され、
\
を使用して文字を引用する必要があります\
、$
、および`
。
これがANSIエスケープコードにどのように影響するかを理解できません。 cat
tedされているBash hereドキュメントでANSIエスケープコードを使用することはできますか?
スクリプトでは、これらの割り当て
normal='\e[0m'
yellow='\e[33m'
これらの文字を文字通りに変数に入れます。つまり、 \e[mエスケープシーケンスではなく。 printf
(または一部のバージョンのecho
)を使用してエスケープ文字を作成できます。たとえば、
normal=$(printf '\033[0m')
yellow=$(printf '\033[33m')
ただし、tput
を使用するほうがはるかに適切です。これは、正しく設定されたすべての端末で機能するためです。
normal=$(tput sgr0)
yellow=$(tput setaf 3)
あなたの例を見ると、あなたが使っているprintf
のバージョンは\e
エスケープ文字として(システムで機能する可能性がありますが、一般に他のシステムに移植できません)。これを確認するには、
yellow='\e[33m'
printf 'Yellow:%s\n' $yellow
literal文字が表示されます。
Yellow:\e[33m
エスケープシーケンスではなく。それらをprintf
形式で配置すると、printf
がそれらを解釈できるようになります(可能な場合)。
参考文献:
この割り当ては、変数にエスケープ文字を配置していません。
normal='\e[0m' yellow='\e[33m'
そのためには、echo -e
printf
または$'...'
(bash)。
Bashを使用しているので、これを使用することもできます。
normal=$'\e[0m' yellow=$'\e[33m'
$
文字列の前に'\e[0m'
。
ただし、エスケープされた文字を取得するポータブルな方法は、次のようにprintfです。
normal="$(printf '\033[0m')" yellow="$(printf '\033[33m')"
エスケープ文字の8進数値(033)は、すべてのPOSIXシェルで有効です。