
rsync
특정 파일을 삭제 한다는 뜻입니다 (예:수천 개의 파일이 포함된 대규모 디렉터리를 효율적으로 삭제합니다.), 이 경우 명령줄의 패턴으로 쉘 스크립트에 할당됩니다.
이것이 지금까지 내 쉘 스크립트에 있는 것입니다.rsync_del.sh
#!/bin/bash
TARGET_DIR=${1}
shift
PATTERNS="${@}"
for patt in ${PATTERNS} ; do
# Both do the same
#INCLUDE_PATTERNS="${INCLUDE_PATTERNS}"' --include='\'"${patt}"\'
INCLUDE_PATTERNS="${INCLUDE_PATTERNS} --include=\"${pattern}\""
done
EMPTYDIR=$(mktemp -d)
echo "Created empty dir ${EMPTYDIR}"
comm="rsync -a --progress --delete ${INCLUDE_PATTERNS} ${EMPTYDIR}/ ${TARGET_DIR}"
echo ${comm}
eval ${comm}
내가 사용하고 싶은 예제 패턴은 *[1-9].txt
, 입니다 *000??9.txt
. 문제는 실행할 때
rsync_del.sh trg_dir '*[1-9].txt'
생성된 명령줄은 다음과 같습니다.
rsync -a --progress --delete --include='*[1-9].txt' /tmp/tmp.51R9hPgkfG/ trg_dir/
(내가 보기에는 괜찮은 것 같지만) 예를 들어 유사한 파일과 일치하는 것입니다 input.dat
(나는 그것을 원하지 않습니다).
이것을 구현/사용하는 올바른 방법은 무엇입니까? 패턴을 올바르게 이스케이프하는 데 문제가 있는 것 같지만 그렇게 할 수 없습니다.
echo
참고: 실행할 명령을 실행하기 전에 변수에 정의해야 합니다.
답변1
실제 상황을 너무 자세히 살펴보지 않음사용여기서는 rsync
대신 명령줄 생성에 중점을 둡니다 rsync
.
#!/bin/bash
target=$1
shift
empty=$( mktemp -d )
trap 'rmdir "$empty"' EXIT
for pattern do
incl+=( --include="$pattern" )
done
rsync --archive --progress --delete "${incl[@]}" --exclude='*' "$empty"/ "$target"
배열( incl
위의 것) 을 사용하면 rsync
같은 문자열 대신 매개변수를 개별적으로 저장할 수 있습니다. 확장은 "${incl[@]}"
배열에서 개별적으로 참조되는 요소가 됩니다. 매개변수 인용은 간단하며 호출이 필요하지 않습니다 eval
. 또한 모든 매개변수 확장에는 올바른 큰따옴표가 필요합니다.
코드의 문제점은 대부분 인용되지 않은 매개변수 확장을 사용한다는 것입니다. 이로 인해 쉘은 변수에 대해 토큰화 및 파일 이름 생성(세계화)을 수행합니다. 이는 공백이 포함된 패턴이나 기존 파일 이름으로 확장될 수 있는 쉘 와일드카드 패턴을 사용할 수 없음을 의미합니다.
/bin/sh
구문이 더욱 간결해지기 때문입니다 .
#!/bin/sh
target=$1
shift
empty=$( mktemp -d )
trap 'rmdir "$empty"' EXIT
for pattern do
set -- "$@" --include="$pattern"
shift
done
rsync --archive --progress --delete "$@" --exclude='*' "$empty"/ "$target"
답변2
명시적으로 포함되지 않은 항목을 제외하여 패턴 목록을 닫아야 한다는 사실을 잊어버렸습니다. 나는 사용했다
comm="rsync -a --progress --delete ${INCLUDE_PATTERNS} --exclude=\"*\" ${EMPTYDIR}/ ${TARGET_DIR}"