array como valor para tar --exclude

2

Eu quero escrever um pequeno script de backup, mas preciso excluir alguns diretórios. Então decidi definir todos os meus diretórios excluídos em uma matriz como essa.

exclude[0] = '/home/user/test1'
exclude[1] = '/home/user/test2'
exclude[2] = '/home/user/test3'

É possível fornecer este array como um parâmetro para o comando tar?

tar -zcvf $FILE $SOURCE --exclude=exclude
    
por ToyRobotic 20.01.2017 / 12:04

4 respostas

1

Como alternativa, você pode usar a opção --exclude-from para lidar com vários locais

tar --exclude-from=/home/user/exclude.txt -zcvf "$FILE" "$SOURCE"

E agora, crie um arquivo com uma expressão regular em cada linha.

cat /home/user/exclude.txt

/home/user/test1
/home/user/test2
/home/user/test3
    
por 20.01.2017 / 12:57
2

com zsh :

exclude=(
  /home/user/test1
  /home/user/test2
  /home/user/test3
)
tar  --exclude=$^exclude -zcvf $FILE $SOURCE

A sintaxe $^exclude faz a expansão acima para

tar  --exclude=/home/user/test1 --exclude=/home/user/test2 \
     --exclude=/home/user/test3 -zcvf the-file the-source

As conchas rc , es e fish fazem esse tipo de processamento com matrizes por padrão, portanto, nesses shells você pode fazer:

tar  --exclude=$exclude -zcvf $FILE $SOURCE

(use set exclude /home/user/test1 /home/user/test2 /home/user/test3 para definir o array em fish ).

    
por 20.01.2017 / 13:11
0

Cada parâmetro para um comando é uma string. Você não pode passar um array para a opção --exclude . Você precisa passar várias opções --exclude ou usar outro método, como --exclude-from . Alguns shells têm uma maneira interessante de interpolar uma matriz com um prefixo adicionado a cada elemento , mas a maioria (sh, bash, ksh,…) não.

Uma coisa que funciona em todos os shells é construir a linha de comando gradualmente.

set tar -zcvf "$FILE" 
set "$@" --exclude='/home/user/test1'
set "$@" --exclude='/home/user/test2'
set "$@" --exclude='/home/user/test3'
"$@" "$SOURCE"

Se você estiver usando bash ou ksh e tiver uma matriz de padrões para excluir, poderá criar a linha de comando, iterando sobre a matriz.

exclude=('/home/user/test1' '/home/user/test2' '/home/user/test3')
exclude_options=()
for x in "${exclude[@]}"; do
  exclude_options+=(--exclude="$x")
done
tar -zcvf "$FILE" "${exclude_options[@]}" "$SOURCE"

As versões mais antigas de ksh e bash não têm o operador += , portanto, elas exigem exclude_options=("${exclude_options[@]}" --exclude="$x") como o corpo do loop.

Em vez de criar uma matriz separada para as opções de exclusão, você pode criar a linha de comando diretamente, em uma variável de matriz nomeada ou na matriz de parâmetros posicionais.

exclude=('/home/user/test1' '/home/user/test2' '/home/user/test3')
set tar -zcvf "$FILE"
for x in "${exclude[@]}"; do
  set "$@" --exclude="$x"
done
 "$@" "$SOURCE"
    
por 21.01.2017 / 01:23
0

O que funcionou para mim é assim:

gv@debi64:$ ls -l *.sh
-rwxr-xr-x 1 root root 56376 Jan 20 12:40 bashtest.sh
-rwxr-xr-x 1 root root  2682 Dec 14 17:58 cpu.sh
-rwxr-xr-x 1 root root  3661 Dec 14 17:58 greptest.sh
-rwxr-xr-x 1 root root  1215 Dec 14 17:58 iconlist.sh
-rwxr-xr-x 1 root root 22096 Jan 20 11:22 inst.sh
-rwxr-xr-x 1 root root   141 Jan 18 09:21 oneshot.sh
-rwxr-xr-x 1 root root   154 Dec 27 17:48 remove.sh
-rwxr-xr-x 1 root root  2393 Dec 14 17:58 twoscreens.sh

$ ex[0]='--exclude=cpu.sh'
$ ex[1]='--exclude=inst.sh'
$ tar "${ex[@]}" -cvf backup.tar *.sh
bashtest.sh
greptest.sh
iconlist.sh
oneshot.sh
remove.sh
twoscreens.sh

Como você pode ver, os arquivos cpu.sh e inst.sh são omitidos pelo arquivo.

Da mesma forma, você poderia construir sua matriz assim:

exclude[0]='--exclude=/home/user/test1'
exclude[1]='--exclude=/home/user/test2'
exclude[2]='--exclude=/home/user/test3'

Como alternativa, o método abaixo também funcionou para mim sem a necessidade de armazenar elementos de matriz "--excluir" na frente.

$ ex[0]='cpu.sh'
$ ex[1]='inst.sh'
$ IFS=,
$ excluded=$(eval echo "--exclude="{"${ex[*]}"})
$ unset IFS
$ tar "$excluded" -cvf backup.tar *.sh

O truque aqui é a segunda linha que irá adicionar na frente de cada elemento da matriz a palavra --excluded= usando a expansão de chave sem precisar de um loop nos elementos da matriz.
Para que a expansão da chave funcione, os elementos da matriz devem ser separados por vírgula e isso é garantido alterando o IFS para vírgula.

$ echo "$excluded"
--exclude=cpu.sh --exclude=inst.sh
    
por 20.01.2017 / 12:21