A resposta de Stephen Rauch descreve o problema. Eu tenho uma solução diferente.
Mas primeiro: por que você está colocando um comando tão longo em uma variável? Só assim você pode imprimi-lo? Por que não apenas usar a opção detalhada (show commands) do shell?
set -v (your_command) set +v
A opção x (rastreamento de execução) é semelhante;
tente o acima com set -x e set +x para ver a diferença.
Se você gosta dos dois, pode combiná-los com set -vx e set +vx .
É uma péssima ideia criar uma string a partir de uma sequência de palavras,
separados por espaços,
e tente separá-lo para recuperar as palavras componentes originais.
Você encontrou uma das armadilhas.
Outra é a possibilidade teórica
que um nome de arquivo pode conter espaço (s);
seria impossível dizer na string de comando cat foo bar baz
que foo bar é um nome de arquivo e baz é outro
(e você viu isso criando a string como cat "foo bar" baz
não funciona bem também).
Estas questões e outras são discutidas aqui:
- Por que meu script de shell se sufoca no espaço em branco ou outros caracteres especiais?
- Implicações de segurança de esquecer de citar uma variável em shells bash / POSIX
Além disso, você não precisa de printf apenas para concatenar strings.
Se você realmente quer construir sua linha de comando no armazenamento, e você está usando o bash, você pode usar uma variável array, assim:
DulicityCMD=(duplicity --log-file "$LOG_FILE" --progress --no-encryption --include="/etc" --include="/var/log" --include="/var/db" --include="/var/www" --include="/home" --exclude="**" / scp://[email protected]:22//home/duplicity/backups/"$VPSNAME")
Observe que eu coloquei $LOG_FILE e $VPSNAME entre aspas.
Você deve sempre citar todas as referências às variáveis do shell
a menos que você tenha uma boa razão para não
e você tem certeza de que sabe o que está fazendo.
Mas Stephen está certo: você não precisa citar as strings constantes
como "/etc" , "/var/log" , "/var/db" e assim por diante.
(Mas, claro, você faz precisa citar "**" ,
porque * é um caractere especial.)
Por questões de legibilidade, você pode dividir o acima em várias linhas.
Observe que a primeira linha diz =
e as linhas subsequentes dizem += ,
porque eles estão adicionando ao que veio antes:
DulicityCMD=(duplicity --log-file "$LOG_FILE" --progress --no-encryption)
DulicityCMD+=(--include="/etc" --include="/var/log" --include="/var/db")
DulicityCMD+=(--include="/var/www" --include="/home" --exclude="**")
DulicityCMD+=(/ scp://[email protected]:22//home/duplicity/backups/"$VPSNAME")
Então você pode fazer
printf "%s\n" "${DulicityCMD[*]}" (to print the command)
"${DulicityCMD[@]}" (to execute the command)
ou use sudo "${DulicityCMD[@]}" , se precisar.
Veja bash (1) para mais informações sobre a sintaxe do bash,
e minha resposta aqui para ver mais sobre essa técnica de matriz.