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?
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?
Respostas:
VAR=$VAR1
é uma versão simplificada do VAR=${VAR1}
. Há coisas que o segundo pode fazer e o primeiro não, por exemplo, fazer referência a 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.
Usar 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 na $IFS
variável especial, espaços em branco por padrão) ou caracteres brilhantes e você não os citar, cada palavra será considerada para geração de nome de arquivo (globbing) cuja expansão gera tantos argumentos para o que você quiser. 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 a seção 2.6.2 do POSIX.1-2008 , as chaves são opcionais.
var1=$var
expansão gera um erro?
export VAR=$VAR1
. Quanto aos aparelhos, eles são opcionais (verifique o quarto parágrafo da seção que você citou; este é o caso em todos os shells pré-POSIX e POSIX).
${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 capturaria muitos caracteres no nome da variável, como em ${VAR1}_$VAR2
(que sem chaves seria equivalente a ${VAR1_}$VAR2
). Expansões mais enfeitadas ( ${VAR:=default}
, ${VAR#prefix}
...) exigem chaves.
Em uma atribuição de variável, a divisão de campo (ou seja, divisão em espaço em branco no valor) e a expansão do nome do caminho (ou seja, globbing) são desativadas, portanto VAR=$VAR1
é exatamente equivalente a VAR="$VAR1"
, em todos os shells POSIX e em todos os sh pré-POSIX que eu ouvi falar . (Ref POSIX: comandos simples ). Pelo mesmo motivo, VAR=*
define de forma confiável VAR
a string literal *
; é claro que VAR=a b
define VAR
como a
desde que b
é uma palavra separada em primeiro lugar. De um modo geral, aspas duplas são desnecessárias onde a sintaxe do shell espera uma única palavra, por exemplo emcase … in
(mas não no padrão), mas mesmo assim é preciso ter cuidado: por exemplo, POSIX especifica queos destinos de redirecionamento ( >$filename
) não exigem aspas nos scripts, mas alguns shells, incluindo o bash, exigem aspas duplas, mesmo nos scripts. Consulte Quando é necessário citar duas vezes? para uma análise mais completa.
Você precisa de aspas duplas em outros casos, especialmente em export VAR="${VAR1}"
(que pode ser escrito de forma equivalente export "VAR=${VAR1}"
) em muitos shells (o POSIX deixa esse caso 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.
IFS
caractere porque quero ter o hábito. A única exceção é que não cito o valor ao fazer uma atribuição de variável (a menos que seja necessário, como quando o valor contém um espaço). Isso torna o destaque da sintaxe do editor mais útil quando há substituições de comandos como FOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. Em vez de colorir tudo a cor "string", recebo o destaque da sintaxe do código aninhado. É também por isso que evito backticks.
>$file
esteja bom nos scripts POSIX, ele não está no bash, mesmo quando não interativo (a menos que a conformidade com POSIX seja imposta $POSIXLY_CORRECT
ou --posix
...).
VAR=$VAR1
, às vezes me surpreendo local VAR=$VAR1
, e lembro-me de trabalhar de maneira diferente em alguns aspectos, em pelo menos algumas conchas. Mas atm, não posso reproduzir a divergência.
local VAR=$VAR1
é como export VAR=$VAR1
, depende do shell.
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.
this='foo'
that='bar'
these="$this"
those='$that'
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, dentre os melhores dentre os quais é considerado melhor prática e para facilitar a leitura. Também porque o Bash é peculiar às vezes e freqüentemente 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).
Embora seja totalmente legal não citar 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.
Agora considere também que a construção "${somevar}"
é usada para operações de substituição. Vários casos de uso, como substituição e matrizes.
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
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
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á apenas arranhando a superfície da "${var}"
construção de substituição. A referência definitiva para scripts de shell Bash é a referência on-line gratuita, TLDP The Linux Documentation Projecthttps://www.tldp.org/LDP/abs/html/parameter-substitution.html