Що означає оболонка, коли ми поміщаємо команду всередині знака долара та круглих дужок: $ (команда)


110

Я просто хочу зрозуміти наступний рядок коду в оболонці. Він використовується для отримання поточного робочого каталогу. Мені відомо, що $(variable)ім'я повертає значення всередині імені змінної, але що $(command)повинно повертатись? Чи повертає це значення після виконання команди? У цьому випадку ми можемо використовувати `для виконання команди.

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

Один і той же вихід може бути взятий із наступного рядка коду також у різній версії оболонки

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

Я не в змозі зрозуміти значення $(cd..і $(dirname.

Може хтось допоможе мені зрозуміти, як ця команда виконується?


1
І ось питання про переваги / недоліки $()порівняно з ``: stackoverflow.com/questions/9449778/…
Ні

Відповіді:


115

Використання $подібного ${HOME}дає значення HOME. Використання $подібних $(echo foo)засобів запускає все, що знаходиться в круглих дужках, в підпакеті і повертає це як значення. У моєму прикладі ви отримаєте, fooоскільки echoвипишете fooдо стандартного


37
Так; $(...)- це кращий спосіб написання команди, ніж спроба використовувати зворотні лапки. Подумайте над написанням: gcclib=$(dirname $(dirname $(which gcc)))/libвикористання зворотних лапок. Ще до того, як ви зіткнетеся з труднощами зробити це в Маркдаун, це важче, тому що вам доведеться уникати зворотних лапок вкладених команд, тоді як у вас немає $(...)позначень.
Джонатан Леффлер

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 )"отримує абсолютний каталог, що містить сценарій, що викликається.

$(...) дозволяє підстановку команд, тобто дозволяє виводу команди замінити саму команду і може бути вкладеною.


1
Вибачте за те, що спізнювались на партію 3 роки, але ви можете пояснити, чому ця заява працює? Ви сказали, dirnameповертає шлях до файлу, який виконується (відносний чи абсолютний до поточної робочої директорії), cdзмінює pwd до цього каталогу та pwdвиводить абсолютний шлях поточного робочого каталогу. Але чому вони до них приєднуються &&? А що буде DIRзаважати, якщо cdне вдасться?
Крістіан

2
@Christian, &&запобігає pwdзапуску, якщо cdне вдасться, такий, що DIRбуде порожнім, а не неправильним каталогом.
Чарльз Даффі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.