Your question is very hard to understand. In particular, you need to copy-paste your code and copy-paste error messages.
That being said, there's a good chance that you made a classic mistake…
When a shell script contains a variable substitution (something like
$1), the result of the expansion is treated as a whitespace-separated sequence of wildcard patterns. The variable is not treated as a single word, but as a list of patterns. So if you write
mv $1 /tmp # <<<< BAD
and you run
myscript "file _name.dat", then the
mv command receives three arguments:
/tmp. If you run
myscript "*.dat", then all the
.dat files in the current directory are moved.
To avoid this, put the variable substitution between double quotes:
mv "$1" /tmp. If you do this,
mv always receives exactly two arguments: the first argument of the script, and
/tmp. It is extremely rare to need to treat variables' values as lists of wildcard patterns, so remember this simple rule:
Always put double quotes around variable substitutions:
"$1", etc. This also goes for command substitutions:
Furthermore, in case the file name begins with a dash (
mv would treat it as an option. To avoid this, pass
-- to mark the end of the options: anything after
-- is a non-option argument (a file or directory name, for
mv). Most commands recognize
-- to mark the end of options.
mv -- "$1" /tmp
If you wanted to invoke your script by writing
myscript file _name.dat /tmp in a shell, that is not possible. The script receives the arguments separately, it doesn't know how many spaces you happened to type on the command line. (This is different from Windows, where a program parses its own arguments. On unix, programs receive a list of arguments.) If you call your script from another shell script, use proper quoting in the calling script as well.