-r 없이 파일 및 하위 폴더 복사

-r 없이 파일 및 하위 폴더 복사

저는 Linux를 처음 사용하고 -r 스위치를 사용하지 않고 생성될 백업 폴더에 디렉터리 내용을 복사하는 Bash 스크립트를 작성하려고 합니다. 디렉토리의 최대 깊이는 2라고 가정합니다. 스크립트에 일부 에코를 넣었더니 for 루프가 첫 번째이자 유일한 인수를 현재 폴더의 경로로 사용한다는 것을 알았습니다. 이는 디렉터리의 모든 파일을 절대적으로 무시합니다. 성공하지 못한 채 코드를 여러 번 변경해 보았습니다. 문법적 오류가 있나요? 논리가 잘못된 걸까요? 답변을 받고 싶습니다. 감사합니다!

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

답변1

cp -r디렉토리 구조를 명시적으로 평면화하려는 경우가 아니면 왜 이것을 사용 하거나 달성할 수 없는지 잘 이해가 안 되지만 rsync -a괜찮습니다.

하위 디렉터리에 대한 경로를 얻으려면 많은 작업을 수행해야 합니다. cd디렉터리로 이동하여 pwd파일로 이동한 다음 파일을 변수로 읽어옵니다. 대신, eg BUrout="$PWD/backup"( $PWD현재 작업 디렉터리의 경로 이름을 담고 있음)를 사용할 수 있습니다.

루프가 디렉터리 이름에 있으므로 파일을 처리하지 않습니다. 당신이 원하는 것은 아마도 for i in "$r"/*; do두 번째 루프에서도 마찬가지일 것입니다.

언제나변수 확장을 큰따옴표로 묶으세요! 예를 들어 if [ "$i" = "$r" ](또한 double이 =아닌 Single이라는 점에 유의하세요). 둘 다 보기 "공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?" 그리고"bash/POSIX 쉘에서 변수를 인용하는 것을 잊어버리는 보안 위험"

스크립트에 단일 cd.진짜디버깅이 어렵습니다.

그 외에는 구문 오류가 없으며 논리가 올바른 것 같습니다.

다음과 같은 것을 제안할 수 있습니다. 이는 여전히 동일한 루프 논리와 코드에서 사용하는 대부분의 동일한 테스트를 사용하지만 호출이 없고 cd디렉터리 이름을 너무 많이 수정할 필요가 없습니다.

#!/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

또는 일부 사람들에게 매력적으로 보이는 단축 구문을 사용하십시오.

#!/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

스크립트는 소스 디렉터리와 대상/대상 디렉터리라는 두 가지 매개 변수를 사용합니다.

$ ./script mydir some_new_backup_dir

cp어떤 명령이 대상 디렉터리의 기존 파일을 덮어쓰는지 여부를 확인하려는 시도는 이루어지지 않습니다 .

또한 두 스크립트 모두 /bin/sh스크립트라는 점에 유의하세요. 그들은 bash쉘 특정 항목을 사용하지 않습니다.


대상 디렉토리가 존재한다고 가정하면 이는 다음과 거의 동일합니다.

find source_dir -maxdepth 2 -type f -exec cp {} target_dir ';'

관련 정보