![Bash 스크립트 일반 문제 [닫기]](https://linux55.com/image/153919/Bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%EC%9D%BC%EB%B0%98%20%EB%AC%B8%EC%A0%9C%20%5B%EB%8B%AB%EA%B8%B0%5D.png)
제가 작업 중인 첫 번째 부분은 bash 셸에서 사용할 수 있는 모든 명령의 텍스트 파일 복사본이 포함된 command_manuals라는 폴더를 만드는 것입니다. 파일 이름은 명령 이름 자체입니다. 목표를 달성하는 스크립트에 영향을 주지 않는 일부 예외 오류 메시지를 제외하고 이 부분을 얻을 수 있었지만 가장 심각한 문제를 먼저 논의하는 것을 선호하므로 지금은 그대로 두겠습니다.
사용 가능한 매뉴얼이 없는 사람들은 여전히 빈 텍스트 파일을 가지고 있는데, 이는 두 번째 부분의 목표로 이어집니다. 이 "0 크기 텍스트 파일"을 제거하고 나중에 사용하고 싶은 단일 목록을 컴파일하는 것입니다. apt-update를 할 때마다 "Undocumented man 7"을 확인하는 부분과 다른 사람들은 잘 알려진 패턴 검색 패키지 중 하나를 사용하여 설명서에 없는 ra, ra, ra 명령에 대해 새로운 것이 추가되었는지 확인합니다. 어쨌든 중요하지 않습니다. 두 번째 부분의 드라마를 지나갈 때까지 지금까지 크기가 0인 폴더 내용의 하위 집합만 인쇄하는 for 루프에 if 조건을 성공적으로 작성했지만 이 내용을 다시 재생하려고 하면 기본적으로 "then"과 "fi" 사이의 명령을 에코하면 빈 파일이 삭제되면서 문제가 시작됩니다.
그러나 그것은 또한 내가 발견한 또 다른 이상한 점과 관련된 추가 질문을 가져왔습니다. 그것은 내가 원하는 방식으로 작동하는 기본 템플릿 스크립트에 표준 #!/bin/bash 가 누락되어 있다는 것입니다. 내 .sh 스크립트 줄, 왜?
template_for_if_delete.sh
TOTALnum=$(wc -l < filesizes.txt);
for i in `seq 1 $TOTALnum`;
do
size=$(sed -n ''$i','$i'p' filesizes.txt)
if [ $size -eq 0 ];
then
echo $(sed -n ''$i','$i'p' filenames.txt);
fi
done;
지금까지실제두 번째 작업을 위한 스크립트:
2부.sh
#!/bin/bash
cd;
cd command_manuals;
rm filenames.txt;
ls -1 > filenames.txt;
TOTALnum=$(wc -l < filenames.txt);
for i in `seq 1 $TOTALnum`;
do filename=echo $(sed -n ''$i','$i'p' filenames.txt);
size=$(stat -c '%s' $filename);
if [ $size -eq 0 ];
then
rm $(locate $(sed -n ''$i','$i'p' filenames.txt));
fi
done;
출력을 생성합니다(위의 for 루프에 정의된 횟수만큼 반복됨).
Try 'stat --help' for more information.
./secondpart.sh: line 9: [: -eq: unary operator expected
./secondpart.sh: line 8: x86_64-linux-gnu-gold.txt: command not found
stat: missing operand
그런 다음 if 문의 변수 "size"를 복잡한 매개변수 확장으로 변경해 보았습니다.
#!/bin/bash
cd;
cd command_manuals;
rm filenames.txt;
ls -1 > filenames.txt;
TOTALnum=$(wc -l < filenames.txt);
for i in `seq 1 $TOTALnum`;
do filename=echo $(sed -n ''$i','$i'p' filenames.txt);
size=$(stat -c '%s' $filename);
if [ ${#size} -eq 0 ];
then
rm $(locate $(sed -n ''$i','$i'p' filenames.txt));
fi
done;
관련 없는 임의의 항목을 삭제하고 싶은지 묻는 관련 출력이 생성되었으며, 그 시점에서 나는 괜찮다고 결정했습니다. 나에게 도움이 된 VM을 망치기 전에 질문을 게시하는 것이 좋습니다. 잘 하셨습니다:
./secondpart.sh: line 8: filenames.txt: command not found
stat: missing operand
Try 'stat --help' for more information.
rm: missing operand
Try 'rm --help' for more information.
./secondpart.sh: line 8: file-roller.txt: command not found
stat: missing operand
Try 'stat --help' for more information.
rm: missing operand
Try 'rm --help' for more information./code>
./secondpart.sh: line 8: filesizes.txt: command not found
stat: missing operand
Try 'stat --help' for more information.
rm: missing operand
Try 'rm --help' for more information.
./secondpart.sh: line 8: file.txt: command not found
stat: missing operand
Try 'stat --help' for more information.
rm: cannot remove adammvirtual/Win10UbuntuVM001_apt_sources_file.txt':
No such file or directory
rm: cannot remove '/home/adamvirtual/mapfile.txt': No such file or directory
rm: remove write-protected regular file '/usr/share/doc/alsa-base/driver/Procfile.txt.gz'?
프롬프트를 벗어나려면 ctrl+를 누릅니다 .C
답변1
문제는 ./secondpart.sh: line 8
어느 것을 설정해야 하는가 입니다 $filename
.
stat
그리고 논쟁이 rm
있어서 그들은 불평을 했습니다. $filename
이러한 오류는 후속 오류입니다.
따라서 8행을 수정해야 합니다.
후속 오류를 방지하려면 거의 항상 set -euo pipefail
첫 번째 오류 시 스크립트를 종료하여 스크립트를 시작해야 합니다.
그러나 전반적으로 스크립트가 너무 복잡하여 wc
루프를 사용하므로 올바른 접근 방식이 아닙니다 for
.sed
파일을 한 줄씩 읽기.
파일 크기가 0인지 확인하는 데 사용하는 대신 stat -c %s
다음을 사용할 수 있습니다.파일 테스트 연산자 -s
, 정확히 그렇게 합니다(실제로 파일 크기가 다음과 같은 경우 반대의 경우를 확인합니다).아니요영).
예를 들면 다음과 같습니다.
xargs -a filenames.txt -I{} sh -c '[ -s "$1" ] || rm -i "$1"' xargs-sh {}
또는
readarray filenames < filenames.txt
for filename in "${filenames[@]}"; do
[ -s "$filename" ] || rm -i "$filename"
done
또는
while IFS= read -r filename; do
[ -s "$filename" ] || rm -i "$filename"
done < filenames.txt
일반적으로 파일 이름에 줄 바꿈이 허용되므로 텍스트 파일에서 파일 이름을 한 줄씩 표시하는 것은 좋지 않습니다. 대신 \0
파일 구분 기호로 항상 널 문자( )를 사용해야 합니다 .