Linux 쉘 스크립트 멈춤 상황 제거

Linux 쉘 스크립트 멈춤 상황 제거

이 스크립트는 휴지통 디렉터리의 내용을 삭제해야 합니다. 이 옵션을 사용 하면 -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

관련 정보