Ответы:
$(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 # Нет такой переменной, как «животные». $ echo $ {animal} s коты $ echo $ animal_food # Нет такой переменной, как «animal_food». $ echo $ {animal} _food кошачья еда
Вы также можете сделать это с кавычками:
$ echo "$ animal" s коты
Или, в качестве упражнения в опциях, вы можете использовать вторую переменную:
$ множественное число = с $ echo $ animal $ множественное число коты
Но это всего лишь шаг 1. Следующий абзац на странице руководства интересен, хотя и немного загадочно:
Если первый символ параметра
является восклицательным знаком ( !
), вводится уровень косвенной косвенности. Bash использует значение переменной, сформированной из остальной части параметра,
в качестве имени переменной; эта переменная затем раскрывается, и это значение используется в остальной части замещения, а не в значении самого параметра . Это известно как косвенное расширение .
… (Исключения) …
Восклицательный знак должен следовать непосредственно за левой скобкой, чтобы ввести косвенное направление.
Я не уверен, как я могу сделать это понятнее, кроме как на примере:
$ animal = cat $ echo $ animal Кот $ cat = табби $ echo $ cat полосатый $ echo $ {! animal} tabby # Если $ animal равно «cat» , то $ {! animal} равно $ cat , то есть «tabby»
Итак, давайте назовем этот шаг 1½. Есть много интересных вещей, которые вы можете сделать на шаге 2:
$ animal = cat $ echo $ {# animal} 3 # длина строки $ echo $ {animal / at / ow} корова # замена
Вы не можете делать ничего из этого без {
... }
фигурных скобок.
Позиционные параметры
Рассмотрим этот искусственный пример:
$ cat myecho.sh эхо $ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 14 $ 15 $ ./myecho.sh Эй, диддл диддл, Кот и скрипка, Корова перепрыгнула через луну. Эй диддл диддл, Кот и скрипка, Хей0 Хей1 Хей1 Хей3 Хей3 Хей4 Хей5
потому что оболочка не понимает $10
, $11
и т.д. трактует , $10
как если бы оно было ${1}0
. Но это понимает ${10}
, ${11}
и т.д., как указано в справочной странице ( «позиционный параметр с более чем одной цифрой»).
Но на самом деле не пишите такие сценарии; Есть лучшие способы иметь дело с длинными списками аргументов.
Выше (наряду со многими другими формами конструкций) более подробно обсуждается в справочной странице оболочки, bash (1) .${parameter…something_else}
Примечание к цитатам
Обратите внимание, что вы всегда должны заключать в кавычки переменные оболочки, если у вас нет веских причин не делать этого, и вы уверены, что знаете, что делаете. Напротив, хотя фигурные скобки могут быть важны, они не так важны, как кавычки.
$ filename = "питомник rhyme.txt" $ ls -ld $ {filename} ls: не может получить доступ к питомнику: нет такого файла или каталога ls: не может получить доступ к rhyme.txt: нет такого файла или каталога $ ls -ld "$ filename" -rwxr-xr-x 1 нуб нуб 5309 июл 2 11:09 детский стишок.txt
Это также относится к позиционным параметрам (т. Е. Аргументам командной строки; например, "$1"
), а также подстановке команд:
$ ls -ld $ (дата "+% B% Y"). txt ls: нет доступа к июлю: нет такого файла или каталога ls: невозможно получить доступ к 2015.txt: нет такого файла или каталога $ ls -ld "$ (date" +% B% Y "). txt" -rwxr-xr-x 1 Нуб Нуб 687 июл 2 11:09 июль 2015.txt
См. Цитаты Bash без экранирования при подстановке команд
для краткого трактата о взаимодействии между кавычками и $(
… )
.
!
.
${!animal}
на самом деле ссылается на переменную, $cat
а не на значение cat». Да, в этом-то и дело. «Как / at становится« c »в echo $ {animal / at / ow}?» А? / at не становится "c"; «Кошка» становится «коровой», когда «у» заменяется на «ау».
В вашем примере $ var и $ {var} идентичны. Однако фигурные скобки полезны, когда вы хотите раскрыть переменную в строке:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
Таким образом, фигурные скобки обеспечивают возможность замены переменной, чтобы получить имя новой переменной, которая сама должна быть заменена.
Я обычно вижу это чаще в строках. Как то так не получится
var="a"
echo "$varRAW_STRING"
Но это будет:
var="a"
echo "${var}RAW_STRING"
Как вы правильно сказали, $()
используется для выполнения команды:
dir_contents=$(ls)
Вы также можете использовать обратные пометки, но я считаю $()
более универсальным. Во-первых, обратные метки не могут быть (легко) вложенными.
date_directory=`ls `date '+%Y-%m-%d'`` # Makes no sense
date_directory=$(ls $(date '+%Y-%m-%d')) # Much better
date_directory=`ls \`date '+%Y-%m-%d'\``
. Но это ужасно уродливо; $(…)
гораздо понятнее и проще в использовании.
`…`
был (только) синтаксис для подстановки команд в течение многих лет , прежде чем был изобретен, так что вам не нужно представить ничего - люди сделали это. $(…)
${
variable_name
}