在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
。除了:
節省三個位元組並使腳本可讀性較差之外,它們之間有任何實際區別嗎?
答案1
行為上沒有真正的區別。這兩個命令都不執行任何操作並以成功狀態退出。 :
強調什麼都不做;true
強調成功的狀態。
strace true
之所以有效,是因為true
它既是 shell 內建指令又是外部指令 ( /bin/true
);:
只是一個內建的 shell(沒有/bin/:
——儘管可能有,而且可能是在非常古老的 Unix 系統上)。在bash中,嘗試
type -a :
type -a true
兩者存在的原因都是歷史性的。如果我沒記錯的話,一些非常早期的 shell 沒有註解語法,因此:
使用了 do-nothing 指令。
存在一些內部差異dash
。查看原始程式碼(可在 git://git.kernel.org/pub/scm/utils/dash/dash.git 取得),顯示了 中的一些不同的程式碼路徑eval.c
,但我無法產生任何明顯不同的行為比special
的輸出中的單字type :
。
答案2
它們在 Bash 中是相同的。查看builtins/colon.def
Bash-4.2 原始碼。
在你的命令中,strace true
你實際上運行的是二進位文件,/bin/true
而不是 bash 內建的 true。
答案3
這些命令之間的差異在於,根據定義:
是特殊內建效用true
而是常規內置POSIX 相容於 shell 中的實用程式。
根據 POSIX 規範,特殊內建處理方式略有不同:
呼叫特殊內建實用程式之前的變數賦值在內建實用程式完成後仍然有效;常規內建實用程式或其他實用程式不會出現這種情況。
這可以在 POSIX 相容的 shell 中進行說明,如下所示:
$ VAR=FOO
$ VAR=BAR :
$ echo "$VAR"
BAR
$ VAR=FOO
$ VAR=BAR true
$ echo "$VAR"
FOO
另一個方面的區別是:
特殊內建實用程式中的錯誤可能會導致執行該實用程式的 shell 中止,而常規內建實用程式中的錯誤不應導致執行該實用程式的 shell 中止。
實際運行的範例程式碼:
$ ( : > ""; 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