「ダッシュ」で実行するとprintfバイトフォーマットが失敗するのはなぜですか?

「ダッシュ」で実行するとprintfバイトフォーマットが失敗するのはなぜですか?

0のASCII 16進コードは0x30です。したがって、を実行してゼロを印刷でき、ゼロprintf '\x30'が印刷されます。

これを myScript.sh というシェルスクリプトに入れて実行すると、ゼロも./myScript.sh印刷されます。

sh -c printf '\x30'ただし、orを実行すると、sh myScript.sh単一バイトとして解釈されるのではなく、リテラル文字「\ x 30」が得られます。

なぜそんなことですか?

(この動作は複数のコンピュータで観察されており、すべてbashを実行していると思います。)

ベストアンサー1

printf一部のシェルの実装(bash少なくともエミュレーションモードでもksh)はこれを16進数として理解します。しかし、これは本当ですzshsh\xHHHHprintf標準

POSIX規格には、1桁、2桁、または3桁の数字のprintfIDが必要です。\oooooo8進数型パラメータの数と型ディレクティブ\0oooで使用される%b引数の数(echo動作と一致させるため)。

/bin/shシステムに表示されるシェルは、一緒に使用すると8進数(すべての標準シェルと同様)を理解しますが、16進数は理解できませdashん。yashprintf

16進数30を8進数に変換すると60なので

$ sh -c 'printf "%b\n" "$1"' sh '\060'
0

または、8進数をパラメータとして渡したくないが、それを静的リテラルとして使用したい場合:

$ sh -c 'printf "\60\n"'
0

(あなたの質問のステートメントの違いに注意してくださいsh -c。ステートメント全体(引数を含む)は、ユーティリティオプションのオプションパラメータとして提供された文字列の一部です。printfあなたの質問の内容は単純な誤字であると仮定します。)sh-c

スクリプトが文字を正常に印刷する理由は、0スクリプトにシェル実行可能ファイルを指す#!-line があるか、bashいいえそのような行はまったくなく、代わりにスクリプトは対話型シェルで実行されますbashbash行なしでシェルスクリプトを実行する場合は、#!シェルを使用してbash実行します(参照:Shebangなしでスクリプトを実行するシェルインタプリタとは何ですか?これについての詳細は詳細)。

明示的なインタプリタ(図を参照)を使用してスクリプトを実行すると、この行sh myScript.sh#!存在する場合)は無視されます。

おすすめ記事