- ベストアンサー
UNIXシェルプログラミングの間違いを探す方法
- UNIXシェルプログラミングの間違いを探す方法を教えてください。
- 質問者はUNIXシェルプログラミングについて知識が浅いため、間違いがあるのかどうかわかりません。
- 具体的な質問内容としては、フォルダ「trash」という名前にいらないファイルを移動させるプログラムを作成したいです。すでに同名のファイルがある場合は、ファイルの最後に「d」をつけ、さらに同名のファイルがあれば「dd」をつけたいです。プログラムの実行にエラーが10回以上発生した場合は、エラーメッセージを表示したいです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
明らかにおかしいのはif文ですね。 Bsh系のif文は、続くコマンドの終了ステータスが正常終了(exit 0)だったらthen節、異常終了(0以外)だったらelse節を実行する、というものです。 計算式で分岐するものではありません。 例えば if echo 'Hello!' ; then echo OK. ;fi だったら、echo 'Hello!'は正常に終了→then節が実行されます。 コマンドを&&や||で継げると、前段のコマンドの終了ステータスによって後段のコマンドを実行するかどうかが決まります。そしてステータスは最後に実行したコマンドのものになります。 コマンド1 && コマンド2 だと、コマンド1が正常終了時に限りコマンド2が実行されます。その結果、全体で AND のような結果になります。 これでは、数値演算や比較に向かないので、 test というコマンドがよく使われます。 test コマンドは 引数を式として解釈し、その結果が真なら正常終了、偽なら異常終了ステータスを返す、というコマンドです。 また、if文を、他のプログラム言語のにように見せるために、 test コマンドは [ ] でも実行されるようになっています。 >if [ test -f "$trashname" && "$error" -le "10" ];then #10回エラーしたら終了 そこで、この文をよく見ると、 ・testコマンドの別名である [ の後に test があります。 ・testを削除すると、 [の終了である ] の前に && がきます。(testコマンドでの AND演算は &&ではありません) ・ && を生かすなら、後半は $error -lt 10 というコマンドとなり、コマンドが見付からない、とエラーとなるでしょう。 全体を[]で使うなら if [ -f "$trashname" -a "$error" -le "10" ];then testを使うなら if test -f "$trashname" -a "$error" -le "10" ;then &&を有効にするなら if test -f "$trashname" && test "$error" -le "10" ;then if [ -f "$trashname" ] && [ "$error" -le "10" ];then > if ($error -gt 10);then これは、 ($error -gt 10) を実行した結果による分岐、という意味になります。 ()でくくったコマンドは「サブシェル(別環境)でも実行」という意味になります。 なんかの数字にはなっているはずなので、たとえば error=11として 11 -gt 10 とコマンドラインに入力したのと同じことになります。おそらく、11というコマンドがみつからず、エラーになるでしょう。 異常終了なので elseが実行されます。 比較を行いたいなら、先程のように test コマンドです。 if test $error -gt 10 ;then if [ $error -gt 10 ];then 実際にどんなコマンドが実行されているかは shの-x や -v を使うとわかります。 sh -x プログラム名 ファイル名