Bash 스크립트의 rm 명령이 변수와 함께 작동하지 않습니다

Bash 스크립트의 rm 명령이 변수와 함께 작동하지 않습니다

mysql 데이터베이스의 백업을 생성하기 위해 bash 스크립트를 작성 중입니다. 사실은 오래된 것을 삭제하고 싶어요.

따라서 유지 관리를 위해 변수를 사용하여 스크립트를 만듭니다.

전체 스크립트가 실제로 작동하고 있지만 작동하지 않는 유일한 것은 이전 스크립트를 삭제하는 것입니다. 나는 이것이 쉬운 부분이라고 생각했습니다.

어쨌든, 이것은 내 코드입니다. 누가 문제가 있는지 말해 줄 수 있나요? rm 명령은 다음을 반환합니다 rm: impossible de supprimer « /path/to/backup/files/*.gz »: Aucun fichier ou dossier de ce type.rm: impossible to delete « /path/to/backup/files/*.gz »: no files or directory of this type

그런데 정말 이상한 점은 우선튜토리얼에서 이 스크립트를 찾았습니다.

둘째, 쉘 명령에서 "rm /path/to/backup/files/*.gz"를 실행하면 예상대로 모든 .gz 파일이 작동하고 삭제됩니다.

#!/bin/bash

USER="***"
PASSWORD="****"
OUTPUT="/path/to/backup/files"

rm "$OUTPUT/*.gz"

databases=`mysql --user=$USER --password=$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`

for db in $databases; do
    if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] && [[ "$db" != "performance_schema" ]] ; then
        echo "Dumping database: $db"
        mysqldump --force --opt --user=$USER --password=$PASSWORD --databases $db > $OUTPUT/`date +%Y%m%d`.$db.sql
        gzip $OUTPUT/`date +%Y%m%d`.$db.sql
    fi
done

감사합니다,

답변1

이것

rm "$OUTPUT/*.gz"

셸 명령줄은 셸에 두 개의 인수( 및 /bin/rm)를 사용하여 실행 하도록 지시합니다 .rm/path/to/backup/files/*.gz

공백 "$쉘 언어 구문의 특수 문자입니다. 공백은 명령 인수를 구분하고, 위와 같은 다른 특수 문자(모두는 아님, 여전히 특수 문자) "를 인용하고 , 일부 확장(예: 여기에서 사용하는 매개변수 확장)에 사용됩니다.$*$$OUTPUT

rm시작 후 파일을 삭제하려고 시도합니다 /path/to/backup/files/*.gz. 귀하의 경우와 같이 파일이 존재하지 않으면 오류가 보고됩니다.

당신이 쓸 때 :

rm /path/to/backup/files/*.gz

또는

rm "$OUTPUT"/*.gz

이번에는 인용되지 않았기 때문에 *와일드카드, 파일 이름 생성 또는 파일 이름 확장이라는 셸의 또 다른 특수 기능이 트리거됩니다. 쉘은 *이 문자를 포함하는 단어를 이 패턴과 일치하는 파일 이름 목록으로 확장하려고 시도합니다.

따라서 a 및 파일을 /path/to/backup/files포함 하면 쉘은 실제로 원하는 것과 더 유사한 3 개의 인수로 호출됩니다 .a.gzb.gzrmrm/path/to/backup/files/a.gz/path/to/backup/files/b.gz

$OUTPUT여전히 자체적으로 인용되어야 한다는 점에 유의하세요. 그렇지 않으면 문자가 포함된 경우 분할될 수 있으며, 와일드 $IFS카드가 포함된 경우(위와 같은 ) *와일드카드의 영향을 받을 수도 있습니다 .

글쓰기에 익숙해지는 것도 좋은 생각입니다.

rm -- "$OUTPUT"/*.gz

이것은 $OUTPUT처음부터 발생하므로 /중요하지 않지만 예를 들어 $OUTPUT변경하는 날은 옵션으로 간주되므로 작동이 중지됩니다.-foo--foo-/...rm

-f스크립트가 대화형이 아닌 경우 이 옵션을 에 추가 할 수 있습니다 rm. 이렇게 하면 일치하는 파일이 없으면 모든 사용자 프롬프트가 비활성화되고 오류가 제거됩니다. 대부분의 쉘은 glob이 일치하지 않으면 패턴을 있는 그대로 응용 프로그램에 전달합니다. rm -f애초에 존재하지 않는 일치하지 않는 파일을 삭제하라는 요청을 받았을 때 불평하지 않습니다. )

답변2

또 다른 접근 방식은 rm을 find 및/또는 xargs와 결합하는 것입니다. 다음은 몇 가지 대안입니다.

find "$output" -name *.gz -type f -delete
find "$output" -name "*.gz" -type f -exec rm '{}' \;
find "$output" -name *.gz -type f -print0 | xargs -0 rm

PS: 파일을 찾으려면 f를 입력하세요.

기본적으로 find는 모든 하위 디렉터리를 검색합니다. 원하는 경우 maxlength 옵션을 사용하여 찾기 작업을 현재 디렉터리로 제한할 수 있습니다.

find "$output" -maxdepth 1 -name "*.gz" -type f -exec rm '{}' \;

rm과 변수를 계속 사용해야 한다면 이것이 나에게 도움이 되었습니다.

out="/home/gv/Desktop/PythonTests/appsfiles";rm "$out"/*.txt
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a ver 1.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/b.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/c.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/d.txt'? y

답변3

다음 파일을 가져온 후 삭제해 보세요.

ARCS=`ls $OUTPUT | grep "\.gz$"`

for _arch in $ARCS; do
    rm -f $_arch
done

관련 정보