저는 시놀로지 NAS를 사용하고 있습니다. 삭제할 파일 목록이 있고 파일 이름에 전체 경로가 나열되어 있습니다 Myfiles.txt
. 파일에는 약 3000줄이 있으며 다음과 같습니다.
"/volume2/NBU/Downloads/AA_To be seen/Life.Itself.2018.1080p.WEB-DL.DD5.1.H264-FGT/RARBG.txt"
"/volume2/nbU/Downloads/AA_To be seen/Find.Me.in.Paris.S01.WEBRip.x264-ION10/Find.Me.in.Paris.S01E16.High.Stakes.Hip.Hop.WEBRip.x264-ION10.mp4"
"/volume2/NBU/Downloads/AA_To be seen/Find.Me.in.Paris.S01.WEBRip.x264-ION10/Find.Me.in.Paris.S01E14.Time.to.Face.the.Music.WEBRip.x264-ION10.mp4"
다음 스크립트를 사용하고 있습니다( ls
나중에 교체되도록 테스트됨 rm -f
).
#!/bin/bash
while IFS="" read -r p;
do
ls "$p"
done < "Myfiles.txt"
불행하게도 스크립트를 실행하면 루프마다 다음 메시지와 함께 오류가 발생합니다.
ls: cannot access "/volume2/NBU/Downloads/AA_To be seen/Life.Itself.2018.1080p.WEB-DL.DD5.1.H264-FGT/RARBG.txt": No such file or directory
ls: cannot access "/volume2/NBU/Downloads/AA_To be seen/Find.Me.in.Paris.S01.WEBRip.x264-ION10/Find.Me.in.Paris.S01E16.High.Stakes.Hip.Hop.WEBRip.x264-ION10.mp4": No such file or directory
ls: cannot access "/volume2/NBU/Downloads/AA_To be seen/Find.Me.in.Paris.S01.WEBRip.x264-ION10/Find.Me.in.Paris.S01E14.Time.to.Face.the.Music.WEBRip.x264-ION10.mp4": No such file or directory
그러나 명령줄에서 직접 해당 줄을 실행하면 작동합니다. 예를 들어:
ll "/volume2/NBU/Downloads/AA_To be seen/Find.Me.in.Paris.S01.WEBRip.x264-ION10/Find.Me.in.Paris.S01E14.Time.to.Face.the.Music.WEBRip.x264-ION10.mp4"
출력은 다음과 같습니다.
-rwxrwxrwx+ 1 Pansysadmin users 275337817 Dec 15 2018 /volume2/NBU/Downloads/AA_To be seen/Find.Me.in.Paris.S01.WEBRip.x264-ION10/Find.Me.in.Paris.S01E14.Time.to.Face.the.Music.WEBRip.x264-ION10.mp4
실행 스크립트를 사용해도 sudo
동일한 오류가 발생합니다.
내가 무엇을 간과하고 있습니까?
답변1
따옴표는 파일 이름의 일부가 아닙니다. 과 같은 파일을 삭제하려고 하는데 "file.txt"
파일 이름이 실제로 입니다 file.txt
.
touch "file.txt" # shell uses quotes; name is simply file.txt
ls "file.txt" # quotes used by shell; success
ls file.txt # no quotes; success
ls '"file.txt"' # outer quotes used by shell to treat word-with-quotes as literal; failure
파일 이름이 올바르도록(즉, 파일 이름 주위에 큰따옴표가 없도록) 파일 이름을 수정하거나 루프를 수정하여 데이터의 잘못된 부분을 제거하십시오.
방금 시도해 봤다는 귀하의 의견을 보았습니다 sudo
. sudo
왜 필요한지 먼저 이해하지 않은 채 그것에 의존하지 마십시오. (여기에서는 그럴 필요가 없습니다.) 그렇지 않으면 어느 날 시스템이 제공하려고 했던 보호 기능을 실수로 우회하여 시스템이 손상될 수도 있습니다.
답변2
크게 하다엠마 루오의 답변,
셸에 명령을 실행하면 명령줄에서 많은 처리와 해석이 수행됩니다. 예를 들어:
- 당신이 입력하면
쉘은 및 의ls foo bar
ls
두 가지 인수로 실행됩니다 . 하지만 입력하면foo
bar
쉘은ls "foo bar"
ls
하나의 인수로 실행됩니다:foo bar
. - 당신이 입력하면
쉘은 , 등과rm north*
rm
같은 많은 매개변수로 실행됩니다north1
. 하지만 입력하면north42
northwest
쉘은rm "north*"
rm
하나의 인수로 실행됩니다:north*
. - 당신이 입력하면
쉘은 이름이 지정된 파일을 생성하고echo Math tells us that 5 > 4.
4.
해당 파일에 내용을 씁니다.Math tells us that 5
등.
- 당신이 입력하면
read
명령이 입력을 읽을 때 처리를 수행하지 않습니다. 특히, 입력 줄에 , 및 같은read
특수 문자가 포함되어 있으면 해당 문자만 변수에 입력됩니다 . 공백과 탭은 일반적으로 여전히 특별한 의미를 가지고 있지만 를 사용하여 억제할 수 있습니다 . 백슬래시( )는 일반적으로 여전히 특별한 의미를 갖지만 성공을 사용하여 억제할 수 있습니다 . 시작과 끝 으로 설정된 파일 이름에도 마찬가지입니다 .*
>
"
p
IFS=
\
read -r
p
"
변수 값을 확장하는 것은 쉘이 수행하는 마지막 작업 중 하나입니다. 예를 들어 다음과 같은 작업을 수행할 수 있습니다.
statement="Math tells us that 5 > 4." echo $statement
쉘은 변수 내용의 문자를
Math tells us that 5 > 4.
확인하지 않기 때문에 (터미널에) 씁니다 .statement
>
참고: 위의 내용은 나쁜 예입니다. 일반적으로 말하면 다음과 같이 말해야 합니다.
echo "$statement"
즉, 따옴표가 있습니다.
그래서 당신이 말할 때
ls "$p"
쉘은
ls
따옴표 문자가 포함된 인수로 실행됩니다. 이는 본질적으로 동일합니다.ls '"/volume2/NBU/Downloads/AA_To be seen/Life.Itself … H264-FGT/RARBG.txt"'
(따옴표 안의 따옴표에 주목하세요) 그리고 실제 파일 이름에는 따옴표가 포함되어 있지 않습니다.