Copiando arquivos e subpastas sem -r

0

Sou novo no Linux, Eu estou tentando escrever um script Bash que irá copiar o conteúdo de um diretório para uma pasta de backup que será criada, sem usar a opção -r. Eu assumi que a profundidade máxima do diretório é 2. Coloquei alguns ecos no script e notei que o loop for leva o primeiro e único argumento a ser o caminho da pasta atual - absolutamente ignora todos os arquivos no diretório. Tentei alterar o código algumas vezes sem sucesso. Existe um erro de sintaxe? A lógica não está certa? Eu adoraria ter uma resposta. Muito obrigado!

pwd > route
r=$(<route)
cd ..
if [ ! -d backup ]; then
    mkdir backup
fi
cd backup
pwd > buroute
BUrout=$(<buroute)
cd "$r"
for i in $r; do
    if [ -f $i ]; then
        cp $i "$BUrout"
    fi
    if [ -d $i ]; then
        if [ $i == $r ]; then
            continue
        fi
        cd "$i"
        pwd > current
        cur=$(<current)'/'
        for file in "$cur"; do
            if [ -f "$file" ]; then
                cp $file "$BUrout"
            fi
        done
        cd ..
    fi
done
    
por RanAB 10.03.2018 / 17:03

1 resposta

2

Eu não entendo muito bem por que você não pode usar apenas cp -r ou rsync -a para isso, a menos que você queira explicitamente achatar a estrutura do diretório, mas não importa.

Você está fazendo muito para obter o caminho para os subdiretórios: cd no diretório, pwd para um arquivo e depois ler esse arquivo em uma variável. Em vez disso, você poderia simplesmente usar BUrout="$PWD/backup" ( $PWD contém o nome do caminho do diretório de trabalho atual).

Você nunca processará nenhum arquivo porque seu loop está sobre o nome de um diretório. O que você deseja é provavelmente for i in "$r"/*; do e, da mesma forma, no segundo loop.

Sempre cite suas expansões variáveis! Por exemplo. if [ "$i" = "$r" ] (observe também o único = , não o dobro). Veja " Por que meu script de shell engasgar em espaço em branco ou outros caracteres especiais? "e" "

Seu script não precisa de um único cd . Scripts que entram e saem dos diretórios são realmente difíceis de depurar.

Além disso, não há erros de sintaxe e a lógica parece estar correta.

Posso sugerir algo assim, que ainda está usando a mesma lógica de looping e principalmente os mesmos testes que seu código está usando, mas sem as chamadas para cd e sem ter que mexer muito nos nomes de diretório:

#!/bin/sh

source="$1"
dest="$2"

mkdir -p "$dest"  # creates destination directory if not already exists

for name in "$source"/*; do
    if [ -f "$name" ]; then
        cp "$name" "$dest"
    elif [ -d "$name" ]; then
        for name2 in "$name"/*; do
            if [ -f "$name2" ]; then
                cp "$name2" "$dest"
            fi
        done
    fi
done

Ou usando a sintaxe de atalho que parece agradar algumas pessoas:

#!/bin/sh

source="$1"
dest="$2"

mkdir -p "$dest"  # creates destination directory if not already exists

for name in "$source"/*; do
    [   -f "$name" ] && { cp "$name" "$dest"; continue; }
    [ ! -d "$name" ] && continue
    for name2 in "$name"/*; do
        [ -f "$name2" ] && cp "$name2" "$dest"
    done
done

Este script recebe dois argumentos, o diretório de origem e o diretório de destino / destino:

$ ./script mydir some_new_backup_dir

Nenhuma tentativa foi feita para verificar se algum dos comandos cp sobrescreveria um arquivo existente no diretório de destino.

Note também que ambos os scripts são /bin/sh script. Eles não usam coisas específicas para o bash shell.

Supondo que o diretório de destino exista, isso é mais ou menos equivalente a

find source_dir -maxdepth 2 -type f -exec cp {} target_dir ';'
    
por 10.03.2018 / 17:17