Что означает в оболочке, когда мы помещаем команду в знак доллара и круглые скобки: $ (команда)

111

Я просто хочу понять следующую строку кода в оболочке. Он используется для получения текущего рабочего каталога. Я знаю, что $(variable)имя возвращает значение внутри имени переменной, но что $(command)должно возвращать? Возвращает ли значение после выполнения команды? В этом случае мы можем использовать `для выполнения команды.

CWD="$(cd "$(dirname $0)"; pwd)"

Тот же вывод можно получить из следующей строки кода также в другой версии оболочки.

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Я не могу понять значение $(cd..и $(dirname.

Может ли кто-нибудь помочь мне выяснить, как выполняется эта команда?

Китис
источник
1
И вот вопрос о преимуществах / недостатках $()vs ``.: stackoverflow.com/questions/9449778/…
Нет

Ответы:

115

Использование $подобного ${HOME}дает значение HOME. Использование $подобного $(echo foo)означает запускать все, что находится в круглых скобках в подоболочке, и возвращать это как значение. В моем примере вы получите, fooпоскольку echoнапишете fooв стандартный формат

Эрик Урбан
источник
37
Да; $(...)- лучший способ написать команду, чем пытаться использовать обратные кавычки. Подумайте о письме: gcclib=$(dirname $(dirname $(which gcc)))/libиспользуйте обратные кавычки. Еще до того, как вы столкнетесь с трудностями, связанными с выполнением этого в Markdown, это сложнее, потому что вам нужно избегать обратных кавычек во вложенных командах, тогда как вы этого не делаете с $(...)обозначениями.
Джонатан Леффлер,
7
Технически $(echo foo)создает подстановку команд, а не подоболочку. Другой текущий ответ дает это право. Я думаю, что подстановка команд выполняется как бы в подоболочке, но это все же разные концепции.
trysis
4
@trysis - подстановка команд определенно выполняется в подоболочке , и на это стоит обратить внимание.
Элиран Малка
2
Я понимаю, что обратные кавычки дают тот же результат, что и $ (), но является ли разница чисто косметической? есть ли причина использовать одно вместо другого, кроме того, что $ () более разборчиво?
Митчелл Трейси
2
«Использование $ like $ (echo foo) означает запускать все, что находится внутри скобок в подоболочке, и возвращать это как значение». ... Это сбивает с толку, так как эта команда $(echo foo)попытается запустить то, что возвращается из круглых скобок, она сначала запустится, а echo fooзатем попытается запустить, fooчто выдает ошибку
Бухгалтер م
21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Может ли кто-нибудь помочь мне выяснить, как выполняется эта команда?

Давайте посмотрим на разные части команды. BASH_SOURCE- это переменная массива bash, содержащая имена исходных файлов. Так "${BASH_SOURCE[0]}"что вернет вам имя файла сценария.

dirnameэто утилита, предоставляемая GNU coreutils, которая удаляет последний компонент из имени файла. Таким образом, если вы выполните свой сценарий, сказав bash foo, "$( dirname "${BASH_SOURCE[0]}" )"вернется .. Если бы вы сказали bash ../foo, это вернется ..; ибо bash /some/path/fooон вернется /some/path.

Наконец, вся команда "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"получает абсолютный каталог, содержащий вызываемый скрипт.

$(...) позволяет подстановку команд, т. е. позволяет выводить команду вместо самой команды и может быть вложенным.

Devnull
источник
1
Извините за опоздание на вечеринку на 3 года, но не могли бы вы объяснить, почему заявление работает? Вы сказали, что dirnameвозвращает путь к исполняемому файлу (относительный или абсолютный по отношению к текущему рабочему каталогу ), cdизменяет pwd на этот каталог и pwdраспечатывает абсолютный путь к текущему рабочему каталогу. Но почему к ним присоединились &&? А что DIRудержит, если cdне удастся?
Кристиан
2
@Christian, &&предотвращает pwdзапуск в случае cdсбоя, так что DIRон будет пустым, а не иметь неправильный каталог.
Чарльз Даффи