でbash
:
$ type :
: is a shell builtin
$ type true
true is a shell builtin
同じように見えますが、同じシステム トレースは提供されません。
$ strace :
strace: :: command not found
$ strace true
execve("/bin/true", ["true"], [/* 82 vars */]) = 0
[snip]
exit_group(0) = ?
strace bash -c : 2>:.txt
と を比較してみましたstrace bash -c true 2>true.txt
が、メモリの場所を除いて違いは見つかりませんでした。
でdash
:
$ type :
: is a special shell builtin
$ type true
true is a shell builtin
わかりました。つまり、これらは同じではありません。help :
とhelp true
はあまり役に立ちませんし、 と では同じ結果を返しますbash
。が3 バイト節約し、スクリプトが読みにくくなることdash
を除けば、これら 2 つの間に実質的な違いはあるのでしょうか?:
答え1
動作に実際の違いはありません。どちらのコマンドも何もせず、成功ステータスで終了します。は :
何もしないことを強調し、true
成功ステータスを強調します。
strace true
true
はシェル組み込みコマンドと外部コマンド(/bin/true
)の両方であるため動作します。:
はシェル組み込みコマンドのみです(ただし、非常に古い Unix システムでは、組み込みコマンド/bin/:
は存在しません)。 bash では、次のように試してください。
type -a :
type -a true
両方が存在する理由は歴史的なものです。私の記憶が正しければ、ごく初期のシェルにはコメント構文がなかったため、:
代わりに何もしないコマンドが使用されていました。
には内部的な違いがありますdash
。git://git.kernel.org/pub/scm/utils/dash/dash.git で入手可能なソースを見ると、 にはいくつかの異なるコード パスがあることがわかりますが、の出力のeval.c
という単語以外には目に見えて異なる動作を生成できませんでした。special
type :
答え2
これらは Bash でも同一です。Bash builtins/colon.def
-4.2 のソース コードを参照してください。
コマンドでは、実際にはbash 組み込みの true ではなくstrace true
バイナリを実行しています。/bin/true
答え3
コマンドの違いは、定義上:
は特別な組み込みユーティリティtrue
は通常の組み込みPOSIX 準拠シェルのユーティリティ。
POSIX仕様によると、特別な組み込み機能以下のように若干異なる扱いとなります。
特別な組み込みユーティリティの呼び出しに先立つ変数の割り当ては、組み込みが完了した後も有効なままです。これは、通常の組み込みユーティリティまたはその他のユーティリティでは当てはまりません。
これは、POSIX 準拠のシェルでは次のように表すことができます。
$ VAR=FOO
$ VAR=BAR :
$ echo "$VAR"
BAR
$ VAR=FOO
$ VAR=BAR true
$ echo "$VAR"
FOO
もう一つの違いは次のとおりです。
特別な組み込みユーティリティでエラーが発生すると、そのユーティリティを実行しているシェルが中止される可能性がありますが、通常の組み込みユーティリティでエラーが発生した場合、そのユーティリティを実行しているシェルは中止されません。
実際のコード例:
$ ( : > ""; echo "You won't see this!" )
sh: 1: cannot create : Directory nonexistent
$ echo "Exit code: $?"
Exit code: 2
$ ( true > ""; echo "Hello!" )
sh: 1: cannot create : Directory nonexistent
Hello!
$ echo "Exit code: $?"
Exit code: 0