:と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と同じ値を返しますdash。 3バイトを節約し、スクリプトを読みにくくすることに加えて、:実質的な違いはありますか?

答え1

行動に実質的な違いはありません。どちらのコマンドも何も実行せず、成功状態で終了します。 :何もしないことを強調し、true成功の状態を強調しなさい。

strace truetrueこれはシェルの組み込みおよび外部コマンド(/bin/true)なので機能します。:ただシェル組み込み(何もありません/bin/:- あるかもしれませんし、おそらく非常に古いUnixシステムにあるかもしれません)。 Bashで試してみてください

type -a :
type -a true

どちらも存在する理由は歴史的です。私の記憶が正しい場合、一部の初期シェルにはコメント構文がなかったため、:何もしないコマンドが使用されました。

内部的に若干の違いがありますdash。ソースコード(git://git.kernel.org/pub/scm/utils/dash/dash.gitで利用可能)を見ると、いくつかの異なるコードパスが表示されますが、テキストとはeval.c大きく異なる動作を生成することはできません。special出力type :

答え2

Bashでは同じです。builtins/colon.defBash-4.2ソースコードを確認してください。

あなたのコマンドはbash組み込みの真ではなく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

関連情報