Якщо в сценарії оболонки я визначаю таку змінну, як FOO=25, чи існує різниця між посиланням на неї як $FOO$і ${FOO}$?
Якщо в сценарії оболонки я визначаю таку змінну, як FOO=25, чи існує різниця між посиланням на неї як $FOO$і ${FOO}$?
Відповіді:
У більшості ситуацій і те, $varі інше ${var}. (Зверніть увагу, що ви не повинні використовувати в $кінці!)
Одним із прикладів, коли вам потрібні фігурні дужки, є те, коли вам потрібно помістити змінну в суцільний рядок.
Приклад:
var=hel
echo ${var}lo
виведе hello.
Щоб відповісти на ваше головне питання, ${foo}називається "розширення параметра" . Якщо бути точним, $сам запуск розширення параметрів { }є фактично необов'язковим згідно зі специфікацією POSIX , але може бути корисним для вказівки кінця назви змінної:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
В основному, $fooі ${foo}ідентичні. Крім випадків, подібних до вищезазначених, або коли ви робите стрижневі маніпуляції , вони є абсолютно рівнозначними.
Однак вам не слід використовувати жоден із них. Основне правило полягає в тому, що, за дуже малим винятком, ви завжди повинні використовувати "$foo"або "${foo}"ніколи $fooабо ${foo}. Ви завжди повинні цитувати свої змінні, щоб не викликати оператора split + glob (докладніше про це пізніше). Ви, звичайно, не хочете $foo$. Фінал $не має значення:
$ foo="bar"
$ echo "$foo$"
bar$
Отже, хоча змінні, які не котируються, іноді добре:
$ echo $foo
bar
Зазвичай їх немає і дійсно слід уникати:
$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Зауважте, що дужки також не допомагають тут:
$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Коли ви використовуєте $fooабо ${foo}, оболонка розділить значення, збережене в змінній на пробіл (це можна змінити, встановивши IFSзмінну на щось інше), у список, а потім кожен елемент списку розглядається як глобальний зразок і розшириться на будь-які відповідні файли чи каталоги. Це відоме як оператор split + glob . Для ілюстрації розглянемо каталог з двома файлами:
$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file2
Тепер встановимо змінну на foo *:
$ foo="foo *"
Що станеться, якщо ми спробуємо перевірити, чи існує файл з таким ім’ям?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
Змінна була розбита на fooі *, оскільки *це підстановка, яка відповідає будь-якій рядку, оболонка повідомляє вам, що файл називається foo *exxists. Однак якщо ми це цитуємо правильно, цього не відбувається:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
Це був тривіальний приклад для ілюстрації цього пункту. Уявіть, якби я використовував rmзамість цього echo.
Отже, перше правило: завжди цитуйте свої змінні. Ви можете використовувати "$foo"або, "${foo}"але цитувати це будь-яким способом. Для більш детальної інформації про безпечне використання змінних ознайомтеся з цими публікаціями:
$ var="foo *"бути $ foo="foo *"? Ви varніде не користуєтесь .
$зрештою! Це буде розглядатися як звичайний символ, а не як частина імені змінної.