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
, $11
etc. 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 $cat
vez 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
}