Caseステートメントを使用してUNIXで詳細モードをオン/オフする方法

Caseステートメントを使用してUNIXで詳細モードをオン/オフする方法

getoptsを使用してシェルスクリプトファイルを生成しようとしています。このプログラムの目的は、プロジェクトからファイルを削除し、ごみ箱とも呼ばれる削除されたディレクトリに保存することです。私はこれをうまくやることができました。

また、getoptコマンド-i(対話型)を使用してCaseステートメントを渡し、ユーザーにファイルを削除するかどうかを尋ねる質問を促すこともできました。

これは、変数「ision」を生成し、Caseステートメントを有効にするときにtrueに設定することによって行われます。以下にコードを挿入しました。何度も試してみましたが、すべてが問題ないようですが、詳細なアクティビティ/モードを追加したいと思います。誰でも私を助けることができますか?

#!/bin/bash

while getopts ":i:v" option ;
do
case "$option" in
i) echo "interactive mode set"
ision=true;
break;;
v) echo "verbose mode"
vison=true;
break;;
esac
done
echo "this is the proof we need"

echo $@

shift $(($OPTIND-2))

echo $@

echo "this is working too"

if [ ! -e ~/deleted ]
then
mkdir ~/deleted
fi

echo "the echo file was made or just created"

if [ $# -eq 0 ]
then
echo "safe_rm missing operand"
exit
fi

echo "all workking on the western front"

for i in $@
do

if [ "$ision" == "true" ]
then
echo "do you want to remobve the file"
echo "variable test $i"
echo "yes or no"
read -p "Enter " answer
if [ "$answer" == "no" ]
then
continue;
fi
fi

if [ ! -f $i ]
then
echo "no such file or directory"
exit
fi
        if [ $i == safe_rm ]
        then

        echo "cant remove safe_rm"
        continue
        fi

        if [ $i == safe_rm_restore ]
        then
        continue
        echo "cant remove safe_rm_restore"

        fi

inode=$(ls -i $i | cut -c -6 )
echo "the inode is $inode "
pathname=$(dirname $i)
if [ $pathname == "." ]
then
pathname=$(pwd)
echo $pathname
fi
basename=$(basename $i)
path=$basename"_"$inode":"$pathname"/"$basename

echo $path

if [ ! -f .restoreinfo ]
then
touch .restoreinfo
fi


echo $path >> .restoreinfo
mv $i ~/deleted/

done

ベストアンサー1

ここでは、コマンドラインの解析に焦点を当てます。

# defaults:
ision=0
vison=0

while getopts "iv" option; do
    case "$option" in
        i)
            echo "interactive mode set"
            ision=1 ;;
        v)
            echo "verbose mode"
            vison=1 ;;
        *)
            exit 1 ;;
    esac
done
shift $(( OPTIND - 1 ))

(( vison )) && echo 'This is a verbose message'

if (( ision )); then
   # interactive code
fi

整数であれば、計算がisionはるかに簡単になります。その後、上記のようにその値をテストvisonできます。(( vison ))

また、無効なコマンドオプション文字列が表示されますgetopts。私が知っている限り、両方のオプションにパラメータはありません。つまり、文字列にコロンがあってはいけません。オプションが引数を取る場合は、次のようにコロンを続けてくださいv:

breakコマンドラインを解析するときにこれを行わないでください。解析が停止します。代わりに、フラグを設定して必要な他のタスクを実行し、ループが続行されるようにします。私はあなたがおそらく次のいずれかであるCについての知識を持っていると仮定します。する必要はステートメントから出てきbreakます。ここは違います。caseswitch

デバッグサポートを除いて、コマンドラインを解析するときに出力を生成しないでください。多くのユーティリティには、互いを取り消すフラグがあります。たとえば、-v冗長モードの場合、-q「静かな」モードで、コード出力が「冗長モードに入った後」「静かなモードに入る」というのはノイズだけです。

しかし、同様のことを行うには(相互排他的なオプションの処理)、次のようにします。

case "$option" in
    q)
        quiet=1
        verbose=0 ;;
    v)
        verbose=1
        quiet=0   ;;

    # etc.

ユーザーが使用する場合、-qv最初quietは1に設定され、次にverbose0に設定され、次に値が反転されます。この場合、コマンドラインを手動で設定したのか、スクリプトを呼び出して設定したのかわからないため、エラーは報告されません。

exit 1不明なコマンドラインオプションが与えられたときに実行されるステートメントを挿入しました。これはユーザーが間違いを犯したという意味であり、その時点からコマンドラインの内容を盲目的に信頼することは危険である可能性があるため、おそらく良いことです。

shift(解決されたオプションの削除)は上記のようにする必要があります。 Shift キーを押すと、$OPTIND - 2引数リストから多くの項目が削除されます。

また、読みやすくするためにインデントを改善し、デバッグとメンテナンスも簡単にしました。


スクリプトの残りの部分は詳細には見られませんでしたが、引用されていない変数拡張がたくさん見つかりました。指定されたファイル名にスペース(または他のスペース文字)が含まれていると問題が発生する可能性があるため、これを行わないでください。

特に$@ループなどで使用される場合は、引用符が必要です。これにより、コマンドライン引数がスペース(より正確には内容$IFS)で区切られるのを防ぎ、名前にグロービングパターン文字が含まれている場合に誤ってファイル名のグロビングを防ぐことができます。

かなり多くのcontinue理論もあります。 IMHOこれらのコードはコードフローに従うのが難しいため、削除する必要があります(特にコードが正しくインデントされていない場合)。それ自体には問題はありませんが、コードがさまざまな条件を適切に処理することで削除できます。少なくとも1つのケースでは、ステートメントのecho直後にステートメントがありますcontinue。これは文が実行されないことを意味しますecho

    continue
    echo "cant remove safe_rm_restore"

おすすめ記事