シェルスクリプトでチェックマーク/クロスマークを印刷する

シェルスクリプトでチェックマーク/クロスマークを印刷する

シェルスクリプトでチェックマークと十字マークを印刷したいです。

#!/bin/bash

echo -e "\xE2\x9C\x94 existing"
echo -e "\xE2\x9D\x8C missing"

なぜこれがうまくいかないのですか?

答え1

コメントでOPが明らかにしたように、彼らはsh file.sh/bin/sh

たとえば、Ubuntuでは、デフォルトのシェルはdash

$ dash
$ printf "\xE2\x9C\x94 missing\n"
\xE2\x9C\x94 missing
$ echo -e "\xE2\x9C\x94"
-e \xE2\x9C\x94

対話型シェルからコマンドを呼び出すときに機能する理由は、デフォルトではユーザー対話型シェル(Ubuntuの場合)によるものです。/bin/bash

スクリプトを正しく実行するには、次のものが必要です。

  • 次のように実行./file.sh
  • 正しいシェルの引数として実行します。bash file.sh

あるいは、シェルに依存しないアプローチが可能である。

# this printf is standalone program, not shell built-in
$ /usr/bin/printf "\xE2\x9C\x94 check mark\n"
✔ check mark

$ python -c 'print "\xE2\x9C\x94 check mark"'
✔ check mark

$ perl -e 'print "\xE2\x9C\x94 check mark"'                                                                              
✔ check mark

答え2

これは\xE2\x9C\x94U + 2714のUTF-8エンコーディングです(チェックマークを繰り返す)特徴。

端末の文字セットがUTF-8で、その文字セットのフォントを使用している場合、この3バイトはチェックマークとしてのみ表示されます。

ターミナルエミュレータの場合、使用する文字セットは通常、起動時にロケールの文字セットです。その端末で実行されているシェルのロケールを変更していない場合は、どの言語を使用しているかがわかります。

locale charmap

printfいくつかの実装はGNUprintfprintf組み込みの両方をサポートしていますzsh(少なくともbashDebianベースのシステムのlkshPOSIX準拠のバリエーション):mksh

$ printf '\u2714\u274c\n'
✔❌

ロケールの文字セットの正しいエンコーディングでこれらの文字を印刷してください(ksh93の組み込みもこの表現をサポートしますが、printfロケール\uXXXXの文字セットに関係なく常にUTF-8に出力します)。printfこれを組み込み、拡張されたエスケープシーケンス(おそらく含む)をサポートするechoシェルは-e通常\uXXXX、その機能もサポートします。

一般的なGNUシステムで使用できる2つの文字セット、AFAICTはUTF-8とGB18030(U + 274CおよびU + 2714文字)です。他の文字セットを使用するロケールでは、printfこれらの文字が存在しないため表示されません。実装によって文字通り印刷されprintfたり、\u274Cエラーで失敗します。

一部のシェル(元のFreeBSD)も参照でこの表記をサポートしていますzshbashksh93mkshsh\uXXXX$'...'

だからあなたはこれを行うことができます:

echo $'\u2714\u274c'

bashシェルによっては、コマンドを解析するとき()、コマンドを実行するとき()、または常にUTF-8(ksh)でzsh実行されるロケールエンコーディングに拡張されます。

POSIXly(Unixシリーズシステムから移植可能)から任意のバイトシーケンスを印刷するには、printf8進表記を使用する必要があります。

\xE2\x9C\x94(U + 2714のUTF-8エンコーディング)は、1行に移植可能に印刷されます。

printf '\342\234\224\n'

そのロケールに合った正しいエンコーディングに変換するには、次の手順を実行します。

printf '\342\234\224\n' | iconv -f UTF-8

POSIX はシステムがサポートする文字エンコードや名前を指定しませんが、上記のコマンドは通常 UTF-8 エンコードをサポートする POSIX システムで動作します。

答え3

生の「切り取りと貼り付け」Unicodeを使用すると、より読みやすい解決策が得られます。

$ echo -e '☑ done\n☒ fail\n☐ to do'
☑ done
☒ fail
☐ to do

関連情報