이 스크립트는 휴지통 디렉터리의 내용을 삭제해야 합니다. 이 옵션을 사용 하면 -a
스크립트를 제거해야 합니다.모두휴지통에 있는 파일. 그렇지 않으면 스크립트는 휴지통에 있는 파일 이름을 하나씩 표시하고 사용자에게 삭제 여부를 확인하도록 요청해야 합니다.
if test ! -f ~/TAM/dustbin/*
then
echo "this directory is empty"
else
for resfile in ~/TAM/dustbin/*
do
if test -f $resfile ; then
echo "Do you want to delete $resfile"
echo "Y/N"
read ans
if test $ans = Y ; then
rm $resfile
echo "File $resfile was deleted"
fi
fi
done
fi
위의 내용은 작동하지만 일부 오류가 보고됩니다.심지어충돌 없이 오류 후에도 다음 코드 줄을 실행합니다.
실수:
./remove: line 4: test: to many arguments
(휴지통에 파일이 2개 이상 있을 때 발생합니다.)
./remove: line 4: test: root/TAM/dustbin/NewFile2: binary operator expected
(이것은 파일이 newfile3이 아닌 newfile2일 때 발생합니다.)
-a
각 파일을 개별적으로 요청하지 않고 폴더의 모든 항목을 삭제하는 방법에 대한 아이디어가 있는 사람이 있습니까?
답변1
첫 번째 질문에는 기본적으로 너무 많은 매개 변수를 제공했습니다. test
(제가 보기에는 붙여넣은 첫 번째 줄이 실제로는 스크립트의 네 번째 줄인 것 같습니다.) 케이스에 파일이 여러 개 있으면 기다려야 test -f file1 file2 file3…
합니다 .test
이항 연산자(예를 들어 "-a"는 AND를 의미함) -f file1
그리고 그 뒤의 다음 표현식 등입니다.
확인을 요청하지 않고 파일을 자동으로 삭제하기 위해 스크립트에 인수를 제공하고 처리하는 경우 test
$1(스크립트의 첫 번째 명령줄 인수가 됨)에서 동일한 인수를 사용할 수 있습니다.
답변2
두 가지 주요 문제가 있습니다.
첫 번째 문제는 첫 번째 명령에서 발생하는 것입니다 test ! -f ~/TAM/dustbin/*
. 먼저 쉘은 와일드카드 패턴을 확장한 ~/TAM/dustbin/*
다음 결과 목록을 test
명령에 전달합니다. 일치하는 파일이 여러 개인 경우에는 작동하지 않습니다.
Bourne 스타일 쉘을 사용하면 위치 인수에 일치 항목 목록을 저장하고 첫 번째 단어가 존재하는지 확인할 수 있습니다(없으면 패턴이 아무것도 일치하지 않습니다).
set ~/TAM/dustbin/*
if ! test -f "$1"; then
echo "this directory is empty"
…
(바라보다이 답변ksh, bash 및 zsh에서 일치하지 않는 glob 패턴을 빈 목록으로 확장하는 방법을 알아보세요. )
디렉터리는 비어 있지 않을 수 있습니다. 여기에는 도트 파일(이름이 로 시작하는 파일 .
, 와일드카드 패턴은 *
이러한 파일을 건너뜁니다. 도트 파일이 있는지 확인하려는 경우 가장 쉬운 이식 방법은 다음을 사용하는 것입니다 find
.
if [ "$(cd ~/TAM/dustbin && find . | head -n 1)" = "." ]; then
echo "this directory is empty"
else
set ~/TAM/dustbin/..?* ~/TAM/dustbin/.[!.]* ~/TAM/dustbin/*
for x; do
if [ -f "$x" ]; then
# $x is a regular file
elif [ -e "$x" ]; then
# $x is a directory or other special file
else
# $x is an unexpanded non-matching pattern
fi
done
fi
( test -f
일반 파일과만 일치하며 -e
파일이 존재하는지 테스트하는 데 사용됩니다.)
스크립트의 또 다른 일반적인 문제는 파일 이름에 쉘 특수 문자가 포함되는 것을 방지하지 않는다는 것입니다."$foo"
변수 대체 및 명령 대체에는 항상 큰따옴표를 사용하십시오 "$(foo)"
.파일 이름에 공백이나 \[?*
.
나는 이것이 학습 운동이라고 생각합니다. 그렇지 않은 경우:
#!/bin/bash
setopt nullglob
rm -ri ~/TAM/dustbin/*
답변3
#!/bin/bash
dir="$HOME/TAM/dustbin"
# check if the dir is empty
shopt -s nullglob
files=("$dir"/*)
if (( ${#files[@]} == 0 )); then
echo "the directory is empty"
exit
fi
# handle command line arguments
all=false
while getopts :a opt; do
case $opt in
a) all=true ;;
?) echo "unknown option: -$OPTARG"; exit 1 ;;
esac
done
shift $((OPTIND - 1))
# perform the deletion
if $all; then
command rm "$dir"/*
else
command rm -i "$dir"/*
fi