: と true の違いは何ですか?

: と true の違いは何ですか?

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 truetrueはシェル組み込みコマンドと外部コマンド(/bin/true)の両方であるため動作します。:はシェル組み込みコマンドのみです(ただし、非常に古い Unix システムでは、組み込みコマンド/bin/:は存在しません)。 bash では、次のように試してください。

type -a :
type -a true

両方が存在する理由は歴史的なものです。私の記憶が正しければ、ごく初期のシェルにはコメント構文がなかったため、:代わりに何もしないコマンドが使用されていました。

には内部的な違いがありますdash。git://git.kernel.org/pub/scm/utils/dash/dash.git で入手可能なソースを見ると、 にはいくつかの異なるコード パスがあることがわかりますが、の出力のeval.cという単語以外には目に見えて異なる動作を生成できませんでした。specialtype :

答え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

関連情報