Eu tento gerar uma linha de comando para um script de backup no shell bash.
Exemplo simples:
EXCLUDES="/home/*/.cache/* /var/cache/* /var/tmp/* /var/lib/lxcfs/cgroup/*";
for FOLDER in $EXCLUDES; do printf -- '--exclude %b\n' "$FOLDER" ; done
Deve resultar em:
--exclude '/home/*/.cache/*' --exclude '/var/cache/*' --exclude '/var/tmp/*' --exclude '/var/lib/lxcfs/cgroup/*'
Mas o problema é que as pastas são expandidas do shell. Eu tentei muitos exemplos com echo/printf/quoting/IFS... mas sem o resultado correto.
Algum jeito de arrumar isso?
Sempre que você tiver que especificar uma lista de nomes de caminho ou nomes de caminho com globs de nome de arquivo, ou apenas geralmente uma lista que você pretende percorrer e/ou usar como uma lista de argumentos para algum comando, use um array.
Se você não usar um array, mas uma string, você não poderá processar coisas com espaços (porque você usa espaços como delimitador na string). Também dificulta o loop sobre o conteúdo da string, pois você terá que invocar a divisão de palavras (não citando a expansão da variável). Mas isso também fará com que o globbing do nome do arquivo aconteça, a menos que você desative isso explicitamente com
set -f
.Na maioria dos shells, mesmo em plain
/bin/sh
, use um array. Emsh
, use a matriz de parâmetros posicionais ($@
).Para
bash
, use uma matriz de strings entre aspas, comoEntão,
Mais tarde,
Observe que a citação é importante em todas as expansões de variáveis acima. A expansão
"${array[@]}"
(assim como"$@"
abaixo) resulta em uma lista de elementos citados individualmente da matriz em questão (mas somente se aspas duplas!).Para qualquer
/bin/sh
escudo: