Sua pergunta é muito difícil de entender. Em particular, você precisa copiar e colar seu código e copiar e colar mensagens de erro .
Dito isto, há uma boa chance de você cometer um erro clássico ...
Quando um script de shell contém uma substituição de variável (algo como $file
ou $1
), o resultado da expansão é tratado como uma sequência separada por espaço em branco de padrões de caractere curinga. A variável não é tratada como uma única palavra, mas como uma lista de padrões. Então, se você escreve
mv $1 /tmp # <<<< BAD
e você executa myscript "file _name.dat"
, o comando mv
recebe três argumentos: file
, _name.dat
e /tmp
. Se você executar myscript "*.dat"
, todos os arquivos .dat
no diretório atual serão movidos.
Para evitar isso, coloque a substituição de variável entre aspas duplas: mv "$1" /tmp
. Se você fizer isso, mv
sempre receberá exatamente dois argumentos: o primeiro argumento do script e /tmp
. É extremamente raro precisar tratar os valores das variáveis como listas de padrões de caracteres curinga, portanto lembre-se desta regra simples:
Always put double quotes around variable substitutions:
"$foo"
,"$1"
, etc. This also goes for command substitutions:"$(mycommand)"
Além disso, caso o nome do arquivo comece com um traço ( -
), mv
o trataria como uma opção. Para evitar isso, passe --
para marcar o final das opções: nada após --
é um argumento não opcional (um nome de arquivo ou diretório, para mv
). A maioria dos comandos reconhece --
para marcar o final das opções.
mv -- "$1" /tmp
Se você quisesse invocar seu script escrevendo myscript file _name.dat /tmp
em um shell, isso não é possível. O script recebe os argumentos separadamente, ele não sabe quantos espaços você digitou na linha de comando. (Isso é diferente do Windows, onde um programa analisa seus próprios argumentos. No unix, os programas recebem uma lista de argumentos.) Se você chamar seu script de outro script de shell, use também o script de chamada no script de chamada.