エコーのみが正しく出力されてもシェルスクリプトを実行すると、このチェックマークが正しく印刷されないのはなぜですか?
スクリプト:
#!/bin/sh
YELLOW='\033[1;33m'
NC='\033[0m' # no color
echo "enter your provider's auth code"
stty -echo
read authcode
oathtool --totp -b $authcode | xclip -i
echo "${YELLOW}\u2714 code copied to clipboard${NC}"
ターミナル出力:コードがクリップボードにコピーされました。
スタンドアロンコマンド:
echo "\u2714 checkmark"
ターミナル出力: ✔チェックマーク
私の殻はzsh 5.8 (x86_64-debian-linux-gnu) 使用rxvt-Unicode-256color端末
答え1
あなたのshebangにはそれがあり/bin/sh
、私はそれがあなたのシステムに存在すると思います/bin/sh
。 Debian が承認した実装ではありません。とにかく、スクリプトで非標準構文を使用しないことをお勧めします。zsh
zsh
sh
sh
sh
\u2714
標準構文ではありませんecho
。これは(おそらく)POSIX標準の次の主なリビジョンで標準になるでしょう$'...'
が、orの引数には表示されません。echo
printf
sh
dash
$'...'
\uXXXX
zsh
' printf
(型引数で%b
)、print
(awを除く-r
)、およびecho
(このオプションが有効または無効になっている場合-E
)、bsdecho
組み込み関数とその内部($'...'
これらのシーケンスが導入される最初のシェル)として認識され、それ自体が引用されます。 ksh93から)。\uXXXX
$'...'
$'...'
#! /bin/zsh -
スクリプトで関数を使用するにはzsh
shebang 。
その後、次のような多くのzsh機能を使用できます。
print -P '%B%F{yellow}\u2714 whatever%f%b'
%F{yellow}
Rompt 拡張を使用すると、P
端末の正しいコードに拡張され、F
鉱石の色を次のように変更できます。黄色(%f
前景色をデフォルト値にリセットして%B
/%b
有効/無効にする勇敢なあなたと同じです\033[1m
.)
では、zsh
次のこともできます。
IFS= read -rs 'authcode?enter auth code: '
より確実にメッセージを表示し、s
自動入力を有効にします。
いずれにせよ、と同様に入力損傷をsh
望み、防止-r
するIFS=
ことができます。read
set -o pipefail
失敗した場合は、oathtool | xclip
失敗と見なされるパイプを使用することもできます。oathtool
xclip
xclip
ロケールの文字エンコーディングにU + 2714文字がないと、エラーprint
で失敗します。zsh: character not in range
標準sh
+ユーティリティ構文では、構文は次のようになります。
#! /bin/sh -
bold_yellow='\033[1;33m'
nc='\033[m' # no color
if [ "$(locale charmap)" = UTF-8 ]; then
check_mark='\0342\0234\0224'
else
check_mark='[X]'
fi
saved_tty_settings=$(stty -g)
trap 'stty "$saved_tty_settings"' EXIT ALRM TERM INT QUIT
stty -echo
printf >&2 "enter your provider's auth code: "
IFS= read -r authcode &&
secret=$(oathtool --totp -b "$authcode") &&
printf %s "$secret" | xclip -i &&
printf '%b\n' "${bold_yellow}${check_mark} code copied to clipboard${nc}"
カラーエスケープシーケンスはここにハードコーディングされており、U + 2714のUTF-8エンコーディングは、ロケールの文字マップがUTF-8の場合にのみハードコーディングされます。
またはこれを行うこともできます:
check_mark=$(printf '\342\234\224' | iconv -f UTF-8 2> /dev/null) ||
check_mark='[X]'
check_mark
ロケールの文字マップが存在する場合(そしてUTF-8
システムがそれをサポートしている場合)、[X]
それ以外の場合はそのロケールの文字マップをインポートします。 GB18030は私が知っている唯一の文字マップで、U + 2714があります。また、主に中国で使用されるUnicodeエンコーディングです(例:zh_CN.gb18030
Debianのロケール)。