シェルスクリプトエラーの処理

シェルスクリプトエラーの処理

私は特定のフォルダ内のファイル(この場合はそのフォルダ内のすべての.csvファイル)を削除する非常に単純なシェルを作成しています。

コードは次のとおりです。

#!/bin/bash
# Used to clean folder

MinVal=0
Files=$(ls -1 *.csv | wc -l)


if [ $Files -gt $MinVal ];then
        rm *.csv
        echo -e "\e[31;43m***** DONE *****\e[0m"    

 else       
        echo -e "\e[31;43mThere is no valid file to delete, please check\e[0m"      


fi

シェルスクリプトは期待どおりに機能しますが、シェルを実行してフォルダに.csvファイルがない場合、端末に次のように表示されます。

ls: cannot access *.csv: No such file or directory

もちろん、次のelseメッセージも表示されます。

There is no valid file to delete, please check

これを回避し、エラー処理をls: cannot access *.csv: No such file or directory直接実行する方法はありますか?else

挨拶。

答え1

これは、シェルが*.csvデフォルトのPOSIX動作のままに渡されるために発生します。lsこれを回避するには、nullglob入力の軸文字列を返すのではなく、何も返さないglobを使用する必要があります。しかし、ここには問題があります。lsファイルが提供されない場合は動作が異なるためです。

ファイル名に改行文字が含まれている場合は、エラーを回避する利点がある次の方法を試してください。

shopt -s nullglob
filenames=( *.csv )  # put all files in an array
files="${#filenames[@]}"  # get number of files

答え2

警告メッセージを表示したくない場合は、ls最も簡単な方法はにリダイレクトすることですstderr/dev/nullたとえば、次のようになります。

Files=$(2>/dev/null ls -1 *.csv | wc -l)

リダイレクトはstderr抑制されます。みんな*.csvディレクトリ内の欠落しているファイルに関連しない可能性があるエラーを含む、このコマンドによって発生したエラー。

ファイル数を数えるより良い解決策は、次のように代わりにfind使用することですls

find . -maxdepth 1 -name "*.csv" | wc -l

実際には、以下を使用して削除を実行することもできますfind

find . -maxdepth 1 -name "*.csv" -delete

私もあなたが-rフラグを使用したことに気づきました。これは、を使用して単純検索を行った後、を使用して再帰削除をrm実行したため、意図しないように見えます。lsrm

しかし、正直なところ、これをスクリプトで書くのは妥当ではないと思います。コマンドを直接実行するのと比較して、このスクリプトの利点は何ですか?つまり、これが何が問題なのか:

# Check for files
ls *.csv

# Delete the files
rm *.csv

これらのコマンドを実行するよりもスクリプトを実行する方が良いのはなぜですか?オーバーヘッドを追加し、あるエラーメッセージを別のエラーメッセージに置き換えるようです。

関連情報