Não se preocupe, você não é o primeiro e não será o último a ser mordido por isso. É a pergunta mais freqüente sobre shells, e é responsável pela maioria dos bugs e vulnerabilidades de segurança encontrados nos shell scripts. Isso é devido a uma má escolha de design do shell Bourne e do shell Korn no histórico Unix anterior.
No shell Bourne e na maioria de seus descendentes (ksh, ash, pdksh, mksh, bash, traço, yash ...), deixar uma variável sem aspas é o operador split + glob.
Melhor demonstrado com:
$ var='*.txt,.*'
$ IFS=',' # default is space tab and newline
$ printf '<%s>\n' $var
<file.txt>
<.>
<..>
O shell dividiu $var
em ,
caracteres e expandiu cada uma das palavras resultantes (que, nesse caso, contêm caracteres curinga) na lista de arquivos que correspondem ao padrão correspondente.
É por isso que, em shells parecidos com Bourne (exceto zsh
), você deve sempre citar suas variáveis (a menos que você queira o split e / ou glob )
$ printf '<%s>\n' "$var"
<*.txt:.*>
Então, no seu caso:
mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"
ou:
mv /sample/pdf/noriginalName.pdf /sample/outputPdf/"${NAME}${Name1}".pdf
(onde você coloca as aspas não importa, desde que as variáveis sejam citadas).
Você pode desativar a divisão apenas com:
IFS=
E você pode desativar o globbing apenas com:
set -f # affects all globbing, not only the one done upon variable expansion.
Com:
IFS=; set -f
Você obtém o mesmo comportamento de zsh
para expansão de parâmetro, sem globbing, sem divisão. Você ainda precisa citar sua variável, no entanto, em
cmd "$var"
Se você quiser que cmd
seja passado a um argumento vazio quando $var
estiver vazio ou não definido (ao contrário do argumento não ). Um exemplo típico é [ -n "$var" ]
, se você não citar $var
, o teste sempre será verdadeiro, pois quando $var
estiver vazio, isso será resolvido como [ -n ]
em vez de [ -n '' ]
.
Em zsh
, globbing e divisão não são feitos implicitamente na expansão da variável (exceto no modo de emulação sh
ou ksh
). Você precisa solicitá-lo explicitamente usando operadores de expansão específicos: $=var
para divisão de palavras, $~var
para globbing (ou ${~var}
; $~=var
para ambos).
Os outros shells que não têm esse tipo de problema são fish
e rc
e seus descendentes ( es
, akanga
).
Em (t)csh
:
cmd "$var"
ajuda, mas não é suficiente, pois não funciona se $var
contiver caracteres de nova linha. Lá você precisa:
cmd $var:q