Що це за змінна форма = $ (…)


9

Що означає таке:

basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

Мене особливо цікавить ця частина:

varible=$(...)

Я знаю, що дужки використовуються для виконання підпроцесу, але що робити, якщо вони використовуються разом з $?


3
Якщо ви використовуєте bash: man bash
загляньте

Відповіді:


16

З посібника Bash ( man bash):

   Командна заміна
       Заміна команди дозволяє вивести команду на заміну
       назва команди Існує дві форми:

              $ (команда)
       або
              `команда`

       Bash виконує розширення, виконуючи команду в підклітині
       оточення та заміщення підстановки команд стандартною
       висновок команди, при цьому всі видалені нові рядки видаляються. Вбудований
       нові рядки не видаляються, але вони можуть бути видалені під час слова
       розщеплення. Заміна команди $ (файл cat) може бути замінена на
       еквівалент, але швидше $ (<файл).

(Це справедливо для всіх Bourne-подібних оболонок, тобто sh, ksh, zsh, і bashт.д., а zshтакож можливість захоплення даних з впровадженими символів NUL в цьому сенсі)

Команда

basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

призначить ім'я каталогу, де розташований скрипт (при цьому також змінює всі косої косої риски на косою косою рискою) basedir. Будь-які помилки, попередження або інші діагностичні повідомлення, які виводяться у стандартний потік помилок, все одно відображатимуться на терміналі ( $(...)фіксує лише стандартний висновок команди).

Оболонка почнеться з виконання найзакоріненішої підстановки команди:

echo "$0" | sed -e 's,\\,/,g'

Вихід цього буде заданий у вигляді рядка dirname, а вихід цього буде призначений змінній basedir.

Подвійні лапки є, щоб переконатися, що жодне розділення слів або глобул імен файлів не буде зроблено, інакше ви можете виявити, що сценарій виходить з ладу або дає дивний вихід, коли $0(ім'я скрипта, включаючи шлях, який використовується для його виконання) містить пробіл символу або символу глобуса з ім'ям файлу (наприклад, ?або *).

Загалом, корисно завжди цитувати розширення (змінні розширення, підстановки команд та арифметичні розширення). Дивіться це питання та його відповіді для відмінного пояснення, чому це гарна ідея.

Якщо сценарій був виконаний як

$ /usr/local/bin/script.sh

то basedirотримає значення /usr/local/bin.

Або на Cygwin:

$ bash c:\\Users\\Me\\script.sh

то basedirотримає значення c:/Users/Me. Подвійні риски в командному рядку в даному випадку - це просто уникнути одиночної косої риски від оболонки. Фактичне значення $0- c:\Users\Me\script.sh.

Ще один спосіб зробити те ж саме, не використовуючи dirname, echoі sedбув би

basedir="${0//\\//}"
basedir="${basedir%/*}"

спасибі, так що це в основному починає розбір з найпотаємніших дужок, правильно? і чому використовуються цитати?
Макс Корецький

@Maximus Правильно. Я оновив свою відповідь додатковою інформацією.
Kusalananda

Можливо, ви повинні сказати, що "справедливо для всіх оболонок, подібних до Борна". Трохи зрозуміліший такий шлях
Сергій Колодяжний

@ Серг, зауважте, що оболонка Борна (як і /bin/shу Solaris 10 або новішої версії) не підтримувала $(...).
Стефан Шазелас

@ StéphaneChazelas Я включу це.
Kusalananda

6

Це означає запустити те, що знаходиться в круглих дужках в підклітині, і повернути це як значення , у вашому випадку призначаючи це varible.


5

varible=$(..)Називається підстановки команд , і це означає не більше , але запустити команду оболонки і зберегти свій висновок змінної або відображати назад з допомогою відлуння - команди. Наприклад, дата та час відображення:

echo "Today is $(date)"

і для збереження його до змінної:

SERVERNAME=$(hostname)

Для отримання додаткової інформації: https://www.cyberciti.biz/faq/unix-linux-bsd-appleosx-bash-assign-variable-command-output/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.