Respostas:
$(command)é "substituição de comando". Como você parece entender, ele executa o command, captura sua saída e a insere na linha de comando que contém a $(…); por exemplo,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}é "substituição de parâmetro". Muitas informações podem ser encontradas na página de manual do shell, bash (1) , sob o cabeçalho “ Parameter Expansion ”:
${parameter}O valor do parâmetro é substituído. As chaves são necessárias quando parâmetro é um parâmetro posicional com mais de um dígito ou quando parâmetro é seguido por um caractere que não deve ser interpretado como parte de seu nome.
Para parâmetros posicionais, consulte " Parâmetros posicionais ", abaixo. Em seu uso mais comum, como mostrado nas outras respostas,
parameteré um nome de variável. O ${…}formulário, conforme indicado no final do parágrafo acima, permite obter o valor de uma variável (ie ) e segui-lo imediatamente com uma letra, dígito ou sublinhado:$variable_name
$ animal = gato
$ echo $ animais
# Não existe variável como "animais".
$ echo $ {animal} s
gatos
$ echo $ animal_food
# Não existe variável como "animal_food".
$ eco $ {animal} _alimento
comida de gato
Você também pode fazer isso com aspas:
$ echo "$ animal" s gatos
Ou, como exercício de opções, você pode usar uma segunda variável:
$ plural = s $ echo $ animal $ plural gatos
Mas este é apenas o passo 1. O próximo parágrafo da página de manual é interessante, embora um pouco enigmático:
Se o primeiro caractere do parâmetro
for um ponto de exclamação ( !), é introduzido um nível de indireção variável. Bash usa o valor da variável formada a partir do restante do parâmetro
como o nome da variável; essa variável é expandida e esse valor é usado no restante da substituição, em vez do valor do próprio parâmetro . Isso é conhecido como expansão indireta .
… (Exceções) …
O ponto de exclamação deve seguir imediatamente a chave esquerda para introduzir a indireção.
Não tenho certeza de como posso deixar isso mais claro, exceto pelo exemplo:
$ animal = gato
$ echo $ animal
gato
$ cat = tabby
$ echo $ cat
malhado
$ echo $ {! animal}
tabby # Se $ animal for "gato" , $ {! animal} será $ cat , ou seja, "gato malhado"
Então, vamos chamar essa etapa de 1½. Há muitas coisas interessantes que você pode fazer na etapa 2:
$ animal = gato
$ echo $ {# animal}Comprimento da corda
3 #
$ echo $ {animal / at / ow}
cow # Substitution
Você não pode fazer nenhuma dessas coisas sem o {... }aparelho.
Parâmetros posicionais
Considere este exemplo artificial :
$ cat myecho.sh eco $ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 14 $ 15 $ ./myecho.sh Hey, diddle diddle, O gato e o rabeca, A vaca saltou sobre a lua. Hey diddle diddle, O gato e o rabeca, O Hey0 Hey1 Hey2 Hey2 Hey3 Hey4 Hey5
porque o shell não entende $10, $11etc. Trata-se $10, como se fosse ${1}0. Mas ele entende ${10}, ${11}etc., conforme mencionado na página do manual ("um parâmetro posicional com mais de um dígito").
Mas não escreva scripts como esse; existem maneiras melhores de lidar com longas listas de argumentos.
O exposto acima (junto com muitas outras formas de construções) é discutido em maior detalhe na página de manual do shell, bash (1) .${parameter…something_else}
Uma nota sobre cotações
Observe que você sempre deve citar variáveis do shell, a menos que tenha um bom motivo para não fazê-lo , e tem certeza de que sabe o que está fazendo. Por outro lado, enquanto os aparelhos podem ser importantes, eles não são tão importantes quanto as aspas.
$ filename = "berçário rhyme.txt"
$ ls -ld $ {nome do arquivo}
ls: não pode acessar o berçário: nenhum arquivo ou diretório
ls: não é possível acessar rhyme.txt: não existe esse arquivo ou diretório
$ ls -ld "$ filename"
-rwxr-xr-x 1 Noob Noob 5309 2 de julho às 11:09 nursery rhyme.txt
Isso também se aplica a parâmetros posicionais (isto é, argumentos de linha de comando; por exemplo "$1") e também a substituição de comandos:
$ ls -ld $ (data "+% B% Y"). txt ls: não pode acessar julho: esse arquivo ou diretório não existe ls: não é possível acessar 2015.txt: não existe esse arquivo ou diretório $ ls -ld "$ (data" +% B% Y "). txt" -rwxr-xr-x 1 Noob Noob 687 2 de julho 11:09 de julho de 2015.txt
Consulte Citações de Bash sem escape na substituição de comandos
para um breve tratado sobre a interação entre aspas e $(… ).
!.
${!animal}está realmente se referindo à variável em $catvez do valor cat.” Sim, esse é exatamente o ponto. “Como / at se torna um“ c ”em eco $ {animal / at / ow}?” Hein? / at não se torna "c"; "Gato" se torna "vaca" quando "em" é substituído por "ow".
No seu exemplo, $ var e $ {var} são idênticos. No entanto, chaves entre colchetes são úteis quando você deseja expandir a variável em uma string:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
Assim, os chavetas fornecem um meio de substituir a variável para que o nome da nova variável seja substituída.
Eu costumo vê-lo mais comumente em strings. Algo assim não funcionará:
var="a"
echo "$varRAW_STRING"
Mas isso irá:
var="a"
echo "${var}RAW_STRING"
Como você disse corretamente, $()é usado para executar um comando:
dir_contents=$(ls)
Você também pode usar backticks, mas acho o $()mais versátil. Por um lado, os backticks não podem (facilmente) ser aninhados.
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'\``. Mas é terrivelmente feio; $(…)é muito mais claro e fácil de usar.
`…`foi a (única) sintaxe da substituição de comando anos antes que $(…)foi inventada, então você não precisa imaginar nada - as pessoas fizeram isso.
${variable_name}