シェルスクリプトでチェックマークとクロスマークを印刷したいと思います。
#!/bin/bash
echo -e "\xE2\x9C\x94 existing"
echo -e "\xE2\x9D\x8C missing"
なぜこれが機能しないのですか?
コメントでOPによって明らかにされたように、彼らはsh file.sh
でスクリプトを呼び出していました。 /bin/sh
がシンボリックリンクされているデフォルトのシェルによっては、Unicode文字をサポートしない場合があります。
たとえば、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
\xE2\x9C\x94
はU + 2714(重いチェックマーク)文字のUTF-8エンコーディングであることに注意してください。
これらの3バイトは、端末の文字セットがUTF-8である(そしてその文字を持つフォントを使用している)場合にのみチェックマークとして表示されます。
端末エミュレーターの場合、使用する文字セットは通常、起動時のロケールの文字セットになります。そのターミナルで起動したシェル内のロケールを変更していない限り、それがどのロケールであったかを確認できます。
locale charmap
GNU printf
およびprintf
、printf
、zsh
のbash
ビルトイン(少なくともDebianベースのシステムではlksh
のPOSIX互換バリアント)をサポートするいくつかのmksh
実装は以下をサポートします:
$ printf '\u2714\u274c\n'
✔❌
これらの文字をロケールの文字セットの正しいエンコーディングで出力するには(ksh93のprintf
組み込みは、その\uXXXX
表記もサポートしますが、ロケールの文字セットに関係なく常にUTF-8で出力します)。 printf
ビルトインがそれをサポートし、エスケープシーケンスを拡張するecho
を持つシェル(通常は-e
を使用)は、通常\uXXXX
もサポートします。
現在、AFAICT、これらの2つのU + 274CおよびU + 2714文字が標準的なGNUシステムはUTF-8およびGB18030で使用できる唯一の2つの文字セットです。異なる文字セットを使用するロケールでは、printf
はこれらの文字は存在しないため、表示できません。実装によっては、printf
が\u274C
を文字どおりに出力するか、エラーで失敗します。
一部のシェル(zsh
、それが発生した場所、bash
、ksh93
、mksh
、FreeBSD sh
)も、\uXXXX
表記での$'...'
表記をサポートしています。
だからあなたはできる:
echo $'\u2714\u274c'
シェルによっては、コマンドが解析されたとき(bash
)、実行されたとき(zsh
)、または常にUTF-8で(ksh)有効だったロケールのエンコーディングに拡張されます。
POSIXly(移植性のあるUnixライクなシステム間で)、任意のバイトシーケンスを出力する場合は、printf
と8進数表記を使用する必要があります。
\xE2\x9C\x94
(U + 2714のUTF-8エンコーディング)は、次のように移植可能な行に出力されます。
printf '\342\234\224\n'
そして、それをロケールの正しいエンコーディングに変換したい場合は、次のようになります。
printf '\342\234\224\n' | iconv -f UTF-8
POSIXは、システムでサポートされる可能性のある文字エンコーディングやその名前を指定しませんが、上記のコマンドは通常、UTF-8エンコーディングをサポートするPOSIXシステムで機能します。
生のユニコードを使用する:
$ echo -e '☑ done\n☒ fail\n☐ to do'
☑ done
☒ fail
☐ to do