Linuxシェルスクリプトのハング状況の削除

Linuxシェルスクリプトのハング状況の削除

このスクリプトはごみ箱ディレクトリの内容を削除する必要があります。このオプションを使用すると、-aスクリプトを削除する必要があります。みんなごみ箱のファイル。それ以外の場合、スクリプトはごみ箱にあるファイル名を1つずつ表示し、ユーザーに削除するかどうかを確認するように求める必要があります。

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

(ごみ箱に複数のファイルがある場合に発生します。)

./remove: line 4: test: root/TAM/dustbin/NewFile2: binary operator expected

(これは、ファイルがnewfile3ではなくnewfile2の場合に発生します。)

-a各ファイルを個別に要求せずにフォルダ内のすべてのアイテムを削除する方法についてのアイデアを持っている人はいますか?

答え1

最初の質問は基本的にあまりにも多くのパラメータを提供しました。test(私のビューには、貼り付けた最初の行が実際にはスクリプトの4行目のようです。)ケースに複数のファイルがある場合は待つ必要がありますtest -f file1 file2 file3…test二項演算子(たとえば、「-a」はANDを意味します)、-f file1その後の次の式などです。

確認を要求せずにファイルを自動的に削除するためにスクリプトに引数を指定して処理する場合は、test$ 1(スクリプトの最初のコマンドライン引数になる)で同じ引数を使用できます。

答え2

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

関連情報