$(command)
- это «подстановка команд».
Как вы, похоже, понимаете, она запускает command
, записывает ее вывод и вставляет ее в командную строку, содержащую $(…)
; например,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}
- это «подстановка параметров».
Много информации можно найти на странице руководства оболочки bash(1) под заголовком « Расширение параметров »:
${parameter}
Значение параметра подставляется.
Скобки требуются, когда параметр является позиционным параметром с более чем одной цифрой, или когда за параметром следует символ, который не должен интерпретироваться как часть его имени.
Позиционные параметры см. В разделе « Позиционные параметры » ниже.
В его наиболее распространенном использовании, как показано в других ответах, parameter
является именем переменной.
Форма ${…}
, как указано в конце параграфа выше, позволяет вам получить значение переменной (т. Е. $variable_name
) и сразу же следовать за ней с помощью буквы, цифры или подчеркивания:
$ animal=cat
$ echo $animals
# No such variable as “animals”.
$ echo ${animal}s
cats
$ echo $animal_food
# No such variable as “animal_food”.
$ echo ${animal}_food
cat_food
Вы также можете сделать это с кавычками:
$ echo "$animal"s
cats
Или, в качестве упражнения в опциях, вы можете использовать вторую переменную:
$ plural=s
$ echo $animal$plural
cats
Но это только первый шаг.
Следующий абзац на странице руководства интересен, хотя и немного загадочно:
Если первый символ параметра является восклицательным знаком (!
), Вводится уровень косвенной косвенности.
Bash использует значение переменной, сформированной из остальной части параметра, в качестве имени переменной; эта переменная затем раскрывается, и это значение используется в остальной части замещения, а не в значении самого параметра.
Это известно как косвенное расширение.
… (Исключения) … Восклицательный знак должен следовать непосредственно за левой скобкой, чтобы ввести косвенное направление.
Я не уверен, как я могу сделать это понятнее, кроме как на примере:
$ animal=cat
$ echo $animal
cat
$ cat=tabby
$ echo $cat
tabby
$ echo ${!animal}
tabby # If $animal is “cat”, then ${!animal} is $cat, i.e., “tabby”
Итак, давайте назовем этот шаг 1½.
Есть много интересных вещей, которые вы можете сделать на шаге 2:
$ animal=cat
$ echo ${#animal}
3 # String length
$ echo ${animal/at/ow}
cow # Substitution
Вы не можете делать ничего из этого без {
… }
скобок.
Позиционные параметры
Рассмотрим этот искусственный пример:
$ cat myecho.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
$ ./myecho.sh Hey diddle diddle, The cat and the fiddle, The cow jumped over the moon.
Hey diddle diddle, The cat and the fiddle, The Hey0 Hey1 Hey2 Hey3 Hey4 Hey5
потому что оболочка не понимает $10
, $11
и т. д. Она обрабатывает $10
как если бы это было ${1}0
.
Но он понимает ${10}
, ${11}
и т.д., Как упомянуто на странице руководства («позиционный параметр с более чем одной цифрой»).
Но на самом деле не пишите такие сценарии; Есть лучшие способы иметь дело с длинными списками аргументов.
Вышеупомянутое (наряду со многими другими формами конструкций ${parameter…something_else}
) более подробно обсуждается на странице руководства оболочки bash (1).
Примечание к цитатам
Обратите внимание, что вы всегда должны заключать в кавычки переменные оболочки, если у вас нет веских причин не делать этого, и вы уверены, что знаете, что делаете.
Напротив, хотя фигурные скобки могут быть важны, они не так важны, как кавычки.
$ filename="nursery rhyme.txt"
$ ls -ld ${filename}
ls: cannot access nursery: No such file or directory
ls: cannot access rhyme.txt: No such file or directory
$ ls -ld "$filename"
-rwxr-xr-x 1 Noob Noob 5309 Jul 2 11:09 nursery rhyme.txt
Это также относится к позиционным параметрам (т. Е. Аргументам командной строки; например, "$1"
), а также к подстановке команд:
$ ls -ld $(date "+%B %Y").txt
ls: cannot access July: No such file or directory
ls: cannot access 2015.txt: No such file or directory
$ ls -ld "$(date "+%B %Y").txt"
-rwxr-xr-x 1 Noob Noob 687 Jul 2 11:09 July 2015.txt
См. Цитаты Bash, не экранированные при подстановке команд, для краткого трактата о взаимодействии между кавычками и $(
… )
.