В чем разница между : и 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. Есть ли между ними вообще какая-то практическая разница, кроме того, что это :экономит три байта и делает скрипты менее читабельными?

решение1

Нет никакой реальной разницы в поведении. Обе команды ничего не делают и завершаются с успешным статусом. :подчеркивает ничегонеделание; trueподчеркивает успешный статус.

strace trueработает, потому что trueэто и встроенная команда оболочки, и внешняя команда ( /bin/true); :это только встроенная команда оболочки (нет /bin/:-- хотя могла бы быть, и, вероятно, была в очень старых системах Unix). В bash попробуйте

type -a :
type -a true

Причины, по которым существуют оба, исторические. Если я правильно помню, в некоторых очень ранних оболочках не было синтаксиса комментариев, поэтому :вместо этого использовалась команда 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.

Согласно спецификации 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

Связанный контент