web-dev-qa-db-ja.com

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

特定のフォルダーのファイル(この場合は、そのフォルダーにあるすべての.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エラー処理に直接アクセスする方法はありますか?

ご挨拶。

2
sandatomo

これは、*.csvは、シェルによって逐語的にlsに渡されます。これは、デフォルトのPOSIX動作です。これを回避したい場合は、nullglobを使用して、入力された逐語的な文字列を返す代わりに、何も返さないグロブが何も返さないようにする必要があります。ただし、ファイルが提供されていない場合はlsの動作が異なるため、これには問題があります。

代わりにこれを試してください。これには、ファイル名に改行が埋め込まれている場合のバグを回避できるという利点があります。

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

lsからの警告メッセージを抑制するだけの場合、最も簡単な方法は、stderrを_/dev/null_にリダイレクトすることです。例:

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

stderrをリダイレクトすると、このコマンドに起因するallエラーが抑制されることに注意してください。これには、_*.csv_ディレクトリ内のファイル。

ファイルをカウントするためのより良い解決策は、findの代わりにlsを使用することです。例:

_find . -maxdepth 1 -name "*.csv" | wc -l
_

実際、findを使用して削除も実行することをお勧めします。

_find . -maxdepth 1 -name "*.csv" -delete
_

また、rmで_-r_フラグを使用していることにも気付きました。これは、lsを使用してフラット検索を実行した後、 rm

率直に言って、このタスクのスクリプトを書くことがあまり意味があるかどうかはわかりません。このスクリプトは、コマンドを直接実行するよりもどのような利点がありますか?言い換えれば、これの何が問題になっていますか?

_# Check for files
ls *.csv

# Delete the files
rm *.csv
_

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

5
igal