it-swarm-pt.com

$ VAR vs $ {VAR} e para citar ou não

Eu consigo escrever

VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"

o resultado final para mim tudo parece o mesmo. Por que devo escrever um ou outro? algum destes não é portátil/POSIX?

150
xenoterracide

VAR=$VAR1 é uma versão simplificada de VAR=${VAR1}. Há coisas que o segundo pode fazer e o primeiro não, por exemplo, referenciar um índice de matriz (não portátil) ou remover uma substring (POSIX-portable). Consulte a seção Mais sobre variáveis do Guia Bash para iniciantes e Expansão de parâmetros na especificação POSIX.

Usando aspas em torno de uma variável como em rm -- "$VAR1" ou rm -- "${VAR}" É uma boa ideia. Isso torna o conteúdo da variável uma unidade atômica. Se o valor da variável contiver espaços em branco (bem, caracteres no $IFS variável especial, espaços em branco por padrão) ou caracteres esbeltos e você não citá-los, então cada Word é considerado para geração de nome de arquivo (globbing) cuja expansão gera tantos argumentos para o que você está fazendo.

$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'

$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename

Sobre portabilidade: De acordo com POSIX.1-2008, seção 2.6.2 , as chaves são opcionais.

108
Shawn J. Goff

${VAR} e $VAR são exatamente equivalentes. Para uma expansão de variável simples, o único motivo para usar ${VAR} é quando a análise captura outros caracteres no nome da variável, como em ${VAR1}_$VAR2 (que sem chaves seria equivalente a ${VAR1_}$VAR2). Expansões mais adornadas (${VAR:=default}, ${VAR#prefix},…) Exigem chaves.

Em uma atribuição de variável, divisão do campo (ou seja, divisão no espaço em branco no valor) e expansão do nome do caminho (ou seja, globbing) são desativados, então VAR=$VAR1 é exatamente equivalente a VAR="$VAR1", em todos os shells POSIX e em todos os sh pré-POSIX que eu já ouvi falar. (Ref POSIX: comandos simples ). Pela mesma razão, VAR=* define de forma confiável VAR para a string literal *; claro VAR=a b define VAR como a, pois o b é uma palavra separada em primeiro lugar. De um modo geral, aspas duplas são desnecessárias quando a sintaxe do Shell espera uma única palavra, por exemplo em case … in (mas não no padrão), mas mesmo assim é preciso ter cuidado: por exemplo, POSIX especifica que destinos de redirecionamento (>$filename) não requer citação em scripts, mas alguns shells, incluindo o bash, exigem aspas duplas, mesmo em scripts. Consulte Quando é necessária a citação dupla? para uma análise mais completa.

Você precisa de aspas duplas em outros casos, principalmente em export VAR="${VAR1}" (que pode ser escrito de forma equivalente export "VAR=${VAR1}") em muitos shells (o POSIX deixa este gabinete em aberto). A semelhança desse caso com atribuições simples e a natureza dispersa da lista de casos em que você não precisa de aspas duplas são por isso que recomendo usar aspas duplas, a menos que você queira dividir e globar.

65

Cotação

Considere que aspas duplas são usadas para expansão variável e aspas simples são usadas para aspas fortes, ou seja, sem expansão.

Expansão:

this='foo'
that='bar'
these="$this"
those='$that'

Resultado:

for item in "$this" "$that" "$these" "$those"; do echo "$item"; done
foo
bar
foo
$that

Vale a pena mencionar que você deve usar a cotação sempre que possível por vários motivos, entre os melhores dentre os quais é considerado melhor prática e para facilitar a leitura. Também porque o Bash é peculiar às vezes e frequentemente por maneiras aparentemente ilógicas ou irracionais/inesperadas, e a cotação muda as expectativas implícitas para explícitas, o que reduz a superfície do erro (ou o potencial para isso).

E embora seja completamente legal citar não e funcione na maioria dos casos, essa funcionalidade é fornecida por conveniência e provavelmente é menos portátil. a prática totalmente formal garantida para refletir intenção e expectativa é citar.

Substituição

Agora considere também que a construção "${somevar}" é usado para operações de substituição. Vários casos de uso, como substituição e matrizes.

Substituição (decapagem):

thisfile='foobar.txt.bak'
foo="${thisfile%.*}"   # removes shortest part of value in $thisfile matching after '%' from righthand side
bar="${thisfile%%.*}"  # removes longest matching

for item in "$foo" "$bar"; do echo "$item"; done
foobar.txt
foobar

Substituição (substituição):

foobar='Simplest, least effective, least powerful'
# ${var/find/replace_with}
foo="${foobar/least/most}"   #single occurrence
bar="${foobar//least/most}"  #global occurrence (all)

for item in "$foobar" "$foo" "$bar"; do echo "$item"; done
Simplest, least effective, least powerful
Simplest, most effective, least powerful
Simplest, most effective, most powerful

Matrizes:

mkdir temp
# create files foo.txt, bar.txt, foobar.txt in temp folder
touch temp/{foo,bar,foobar}.txt
# alpha is array of output from ls  
alpha=($(ls temp/*))

echo "$alpha"         #  temp/foo.txt
echo "${alpha}"       #  temp/foo.txt
echo "${alpha[@]}"    #  temp/bar.txt  temp/foobar.txt  temp/foo.txt
echo "${#alpha}"      #  12 # length of first element (implicit index [0])
echo "${#alpha[@]}"   #  3  # number of elements
echo "${alpha[1]}"    #  temp/foobar.txt # second element
echo "${#alpha[1])"   #  15 # length of second element

for item in "${alpha[@]}"; do echo "$item"; done
temp/bar.txt
temp/foobar.txt
temp/foo.txt

Tudo isso está arranhando a superfície do "${var}" construção de substituição. A referência definitiva para scripts do Bash Shell é a referência on-line gratuita, TLDP The Linux Documentation Project https://www.tldp.org/LDP/abs/html/parameter-substitution.html

9
SYANiDE
ls -la

lrwxrwxrwx.  1 root root      31 Nov 17 13:13 prodhostname
lrwxrwxrwx.  1 root root      33 Nov 17 13:13 testhostname
lrwxrwxrwx.  1 root root      32 Nov 17 13:13 justname

fim então:

env=$1
    if [ ! -f /dirname/${env}hostname ]

vale a pena mencionar como um exemplo mais claro do uso de curvas

0
ninjabber