Don't worry, you're not the first and won't be the last one to be bitten by that. It's the most frequently asked question about shells, and that's responsible for most bugs and security vulnerabilities found in shell scripts. That's due to a bad design choice of the Bourne shell and the Korn shell in the earlier Unix history.
In the Bourne shell and most of its descendants (ksh, ash, pdksh, mksh, bash, dash, yash...), leaving a variable unquoted is the split+glob operator.
Best demonstrated with:
$ var='*.txt,.*'
$ IFS=',' # default is space tab and newline
$ printf '<%s>\n' $var
<file.txt>
<.>
<..>
The shell has split $var
on ,
characters and expanded each of the resulting words (which in this case contain wildcard characters) in the list of files matching the corresponding pattern.
That's why, in Bourne-like shells (except zsh
), you must always quote your variables (unless you do want the split and/or glob)
$ printf '<%s>\n' "$var"
<*.txt:.*>
So in your case:
mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"
or:
mv /sample/pdf/noriginalName.pdf /sample/outputPdf/"${NAME}${Name1}".pdf
(where you put the quotes doesn't matter as long as the variables are quoted).
You can disable the splitting only with:
IFS=
And you can disable the globbing only with:
set -f # affects all globbing, not only the one done upon variable expansion.
With:
IFS=; set -f
You get the same behaviour as zsh
for parameter expansion, no globbing, no splitting. You still need to quote your variable however in
cmd "$var"
If you want cmd
to be passed one empty argument when $var
is empty or unset (as opposed to no argument at all). A typical example is [ -n "$var" ]
where if you don't quote $var
, the test will alway be true since when $var
is empty, that resolves to [ -n ]
instead of [ -n '' ]
.
In zsh
, globbing and splitting is not done implicitly upon variable expansion (except in sh
or ksh
emulation mode). You have to request it explicitly using specific expansion operators: $=var
for word splitting, $~var
for globbing (or ${~var}
; $~=var
for both).
The other shells that don't have this kind of problem are fish
, and rc
and its descendants (es
, akanga
).
In (t)csh
:
cmd "$var"
helps but is not enough, as it doesn't work if $var
contains newline characters. There, you need:
cmd $var:q
Name
orNAME
? – Cristian Ciupitu Aug 14 '14 at 12:30