質問: unixシェルプログラミング間違い探してくださる方。。。 unixシェルプログラミング間違い探してくださる方。。。 わかりません、実行できません、おねがいします 知識浅いので"ハア?"って思うかも・・^^; trashという名のフォルダにいらないファイルを移動(sh プログラム名 ファイル名 で) すでに同名のファイルがあればファイルの最後にdをつける(なんでもいいんですが、) dがついてるファイルがすでにあるならddをつける #!/bin/sh trashname="$1" error=0 cd trash/ || exit 1 #trashへ移動 while : do if [ test -f "$trashname" && "$error" -le "10" ];then #10回エラーしたら終了 trashname="trashname""d" #名前→名前d error=`expr $error + 1` echo "$error" else break fi echo "no match" done if ($error -gt 10);then echo "$trashname :eroor" else mv ../"$1" "$trashname" echo "congratulations." fi
回答: 明らかにおかしいのは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 プログラム名 ファイル名