• ベストアンサー
  • すぐに回答を!

シェルスクリプト bashのtestコマンドが動きません

こんにちは、ど素人なのにシェルスクリプト仕事で書かされ苦しんでます。 SUN-solaris8で動作したシェルをLinuxE3.0へ移動させたら testコマンドでエラーになりました。 SUN-solaris8ではbsh LinuxE3.0ではbashです。 test -s file名は両方で認識するようですが、 test -s ../directory名/file名で指定して 実行するとSUNでは動作したのですが Linuxではわけの分からないメッセージが出て終了。 Linuxで % sh と打つと/bin/bash % test と打つと /XXX/usr/binだったかな?パス忘れました。 % man bashでマニュアル見るとtestは[]で囲め?   英語だから良く分からなかった。   疲れたので今日は諦めました。 testコマンドで良い解決法ご教示願います。 情報が不足なら指摘いただいた物を追加いたします。

共感・応援の気持ちを伝えよう!

  • 回答数4
  • 閲覧数2529
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • 回答No.2
  • notnot
  • ベストアンサー率47% (4591/9637)

SUNであろうがLinuxであろうが、test -s の後に書けるファイル名は1つだけです。SUNで、test -s *.log が動いていたのはたまたまマッチするファイルが0または1つだけだったのでしょう。 >if test -s XXXX.log || YYYY.log これは、間違いです。これは、 XXXX.logが存在してファイルサイズが0でなければ、この後のthen部分を実行する。XXXが存在しないか、ファイルサイズが0なら、「 YYYY.log というコマンド」を実行するその結果が真ならその後のthen部分を実行する。 という意味不明の記述です。 何をしたいのか説明文(?)から読み取れないのですが、*.log というファイルが1つ以上あり、それらすべてサイズが0でないということを調べたいのでしょうか? FLAG=true for i in *.log do if test -s $i; then :; else FLAG=false; fi done if $FLAG then echo "すべての *.log ファイルのサイズが非ゼロ" else echo "*.logが存在しないか、少なくとも一つの *.log ファイルのサイズがゼロ" fi

共感・感謝の気持ちを伝えよう!

質問者からの補足

ご回答ありがとうございます。 testコマンドは*は使用不可能だったことが分かり助かりました。 実行したいことは if test -s (XXXX.log || YYYY.log ||・・・・) と書くのでしょうか。 コーディングの仕様は あるプログラムを動かしたとき 正常動作ならば ifの条件( *.log というファイルが1つ以上あり、 それらすべてサイズが0でないなら) thenの実行 elseの条件( 動かしたプログラムが異常なら途中でストップし、*.log が1つも 存在しない) だから elseでexitさせたい という希望です。 *.logが出れば必ずサイズがあるのは前提です。 ひょっとして想定外の不具合で*.logが出てもファイル サイズが0はありうるかもしれませんが、今回は 考慮に入れてませんでした。 お書きになったfor 文は解決のヒントになりました。 testコマンドでは*は無理ということも勉強になりました。 Linuxがはきだしたコメント見ればわかったはず。 反省してます。 やはり第3者に作ったプログラムを読んでいただくことは 技術の向上に欠かせないです。でもうちの環境では 出来る人はいるのですが、給料成果主義のせいか いつ尋ねても、忙しいから自分でやれで終わります。 自分で本を購入したり、HPで検索しながら 使えそうなコマンドを探して書いている状況です。 分かりにくい文章を丁寧に判読してくださりありがとうございます。 こちらの検討した仕様に考慮不足や補足情報が必要でしたら ご指摘ください。

関連するQ&A

  • [シェルスクリプト内で bashコマンド後のコマンドが実行されない]

    [シェルスクリプト内で bashコマンド後のコマンドが実行されない] 以下の様にシェルスクリプトを記述するとコマンド2が実行されません。 #! /bin/sh コマンド1 bash コマンド2 bash環境でコマンド2を実行させるにはどうしたら良いのでしょうか?

  • Linuxでシェルスクリプトがフルパスだと実行できない

    Linuxでシェルスクリプトがフルパスだと実行できない こんにちは 現在linuxでシェルスクリプトを記載していて、やっと出来た!と思ったら、なぜかフルパスで実行すると失敗します。 中身は例えば #!bin/sh echo "hello" とし、ファイル名をtest.shとします。 実行時にカレントからだと上手くいきます。 ./test.sh ただし、フルパスで実行するとうまくいきません。 ./home/user/test.sh エラーは以下 bash: ./home/dv3/tet.sh:No such file or directory 所有者はrootでグループもrootにしてあります。 シェルの権限は755にして、rootで実行しています。 なぜカレントだと上手くいき、フルパスだと上手くいかないのでしょうか? パスが必要なコマンドも入っていないのに。。。 どなたかご教授いただけると幸いです。 宜しくお願い致します。

  • bashシェルスクリプトで空白がある場合のコマンドは変数にどう記述したらいいのでしょうか?

    bashのシェルスクリプトで #!/bin/bash -x CMD=/bin/service portmap restart;/bin/service nfslock restart;/bin/service nfs restart $CMD としたのですが2行目で既にコマンドが実行されてしまいます。 空白がある場合のコマンドは変数にどう記述したらいいのでしょうか?

その他の回答 (3)

  • 回答No.4
  • notnot
  • ベストアンサー率47% (4591/9637)

>FLAG=true   ←FALG変数にtrueを設定 >for i in *.log  ←全logファイルチェックのfor文 >do >if test -s $i   ←1つ目のlogの存在確認 1つ目とは限りませんけどね。 >then :; ←:は何の役目ですか? 1つ目のlogが存在すれば何もしない : は何もしないコマンドです。条件を逆にして、 if test ! -s $i ; then FLAG=false; fi でもいいんですが。 >else FLAG=false;  ←1つ目のlogの存在したのでFLAG変数にfalseが設定 -s $i が偽のときつまり、ファイルが存在しないかサイズが0のとき設定 >fi >done ←logがなくなるまでforを繰り返す > >if $FLAG  ←$FLAGって何をしめしますか? $FLAG は、true か false かどちらかです。 一回もforループ内のelseに来ないとき、つまりすべての*.logファイルのサイズが非0のときにFLAGはtrueのままです。一度でもelseに来ていればつまりどれかひとつでもファイルサイズが0ならfalse。 *.logという名前にマッチするファイルがひとつもなければ、forループはiの値が"*.log"という文字列のままで一度だけ実行され、そういう名前のファイルはないので、test -s $i は偽になって FLAG=false になります。 $FLAGがtureかfalseかによって、最後のif文のthen部かelse部かのどちらかが実行されるわけです。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

こんばんは 本当に助かりました。 FOR文を使うのは気が付かなかったです。 ちゃんと動きました。 一つ疑問があって シェル実行中に 下のメッセージが出るのですが include .cshrc_Lx これは何か設定がまずいのですか?

質問者からの補足

ご回答ありがとうございます。 >$FLAGがtureかfalseかによって、最後のif文のthen部かelse部かのどちらかが実行されるわけです。 IF$FLAGってくっつけてもOKですか?IFと$間に空間がいるとか。 trueの場合最後のif文のthen部かelse部はthenの部分で、 falseのときはelseが実行されるんですね。 月曜日に会社へ行ってやってみます。 成功したら、とっても嬉しいです。 月曜の晩までお礼お待ちくださいませ。

  • 回答No.3
  • notnot
  • ベストアンサー率47% (4591/9637)

test で複数ファイルを調べるなら、 test -s XXX.log -a -s YYY.log -a -s ZZZ.log と、-a でつなぎます。and の意味です。or は -o 。 X || Y というのは、コマンド A を実行してエラーのときに B を実行するという意味です。 私の書いたのでご希望の仕様になっていると思いますが、for 文を使っちゃだめなんですか?(ファイルが存在しないかサイズゼロのときFLAGがfalseになって次のifでそれを調べる)

共感・感謝の気持ちを伝えよう!

質問者からの補足

ご回答ありがとうございます。 FOR文でもなんでも使ってよいです。 提案してくださったスクリプトを 自分なりに解読してみました。 FLAG=true   ←FALG変数にtrueを設定 for i in *.log  ←全logファイルチェックのfor文 do if test -s $i;   ←1つ目のlogの存在確認 then :; ←:は何の役目ですか? 1つ目のlogが存在すれば何もしない else FLAG=false;  ←1つ目のlogの存在したのでFLAG変数にfalseが           設定 fi done ←logがなくなるまでforを繰り返す if $FLAG  ←$FLAGって何をしめしますか? then echo "すべての *.log ファイルのサイズが非ゼロ" else echo "*.logが存在しないか、少なくとも一つの *.log ファイルのサイズがゼロ" fi if $FLAGこのIF文のは$FLAGは何を判定してますか?

  • 回答No.1
  • notnot
  • ベストアンサー率47% (4591/9637)

具体的にどのようなディレクトリ構成で、具体的にどのようなコードを書いて、具体的にどのようなエラーメッセージが出たんでしょう? >Linuxで >% sh と打つと/bin/bash >% test と打つと /XXX/usr/binだったかな?パス忘れました。 この文章も意味不明です。説明力が無いのなら、そのままコピーペーストしてください。

共感・感謝の気持ちを伝えよう!

質問者からの補足

毎度ご迷惑おかけします。 SUNからLinuxへシェルを移植して急に動かなかったので 気が動転してました。 スクリプトは簡略化させていただきました。 やりたいこと あるプログラムを実行したあと、 スクリプトでlogファイルの存在(1個以上かつ名前も複数) を調べるのにXXXX.logやYYYY.logに正常終了ならXXXX.logやYYYY.log ファイルの最終行にFINISHが出る仕様なのでgrepで拾う。 異常終了はxxx.logファイル自体が出ない その時点でエラーストップさせたい。 別の場所にERRORのログファイルが出る if test -s *.log then grep FINISH *.log > FINISH_log else echo ' [ERROR]' exit fi このスクリプトを実行したら test: too many arguments とメッセージでた。複数ファイルはいけませんという意味らしい。 grep FINISH *.log > FINISH_log は上手く手来ました。 Linuxで、testコマンドは*(ワイルドカード)指定で 複数ファイルの参照は仕様上無理ですか? なにか上手い解決方法があれば、ご教示お願いします。 if test -s XXXX.log || YYYY.log は認識できました。 echo $status は 0 ゼロリターンでした。 このXXXX.logファイルはいろんな名前(ただし.logは共通) で100個程度出てきます。やはり全てのファイル名 をダブルパイプで連結しかありませんか?

関連するQ&A

  • シェルスクリプト(Bash偏)の実行ファイルに関するご質問があります。

    シェルスクリプト(Bash偏)の実行ファイルに関するご質問があります。 ファイル名を変更するシェルスクリプトをbashで行おうとプログラムを作成したのですが、 実行するとbad interpreter: ディレクトリではありません とメッセージが出て終了します。記述に誤りがあるのか、実行の仕方が悪いのか分かりません。教えて下さい。 シェルの記述内容は ファイル名をtest.sh #!/bin/bash/ -f mv A.txt A.ori exit 実行方法として #>chmod x+a test.sh #>./test.sh で行いました。そうしたら、bad interpreter: ディレクトリーではありません とメッセージが出ます。 ちなみに #>. test.sh で実行するとターミナルがシェルの実行と同時に閉じてしまいますが、シェルを実行したディレクトリーを確認すると、処理が終わっておりました。

  • シェルスクリプトの1行目に#!を書いてもダメなのはなぜ?

    test.shというシェルスクリプトを #!/bin/bash echo "bash test" のように書き、chmod +x test.shを実行し、 test.shと入力すると、bash testが表示されるはずですが、 エラーbash: test.sh :command not found が出ます。which bashでパスを見ると /bin/bashなので、問題ないはずなんですが。 ちなみに、bash test.shと入力すると、正常に実行されます。 同様のことがperlスクリプト #!/usr/bin/perl print "perl test\n"; についても起こります。 何か設定がまずいのでしょうか? RedHatLinux7.2を使用しています。

  • シェルスクリプト コマンドを変数にした時の呼び方

    はじめまして、シェルスクリプトを勉強中の者です。 コマンドを変数にいれて、まとめました。 しかしコマンドの変数を呼びこもうとするとエラーになります。 ============================================ #!/bin/sh GREP="grep" cat "${GREP} '^[0-9]' /home/hoge/test.nicdf" ============================================ ================ シェル実行結果 ============= $ ./test.sh cat: grep '^[0-9]' /home/hoge/test.nicdf: そのようなファイルやディレクトリはありません どう書けば、エラーにならずに正常に動作するでしょうか? ご教授の程よろしくお願いします。

  • シェルスクリプト間で排他をとりたい

    環境 linux(redhat) 使用シェル bash シェルスクリプトAとシェルスクリプトBを作成し、 シェルスクリプトAが動作している間は、シェルスクリプトBの動作を禁止したいと考えています。 例えば、シェルスクリプトAが起動している状態で、シェルスクリプトBが起動されたとき、シェルスクリプトBは、シェルスクリプトAが起動していることを検知して、自発的に処理を終了するようにしたいと考えています。 上記のような仕組みをシェルスクリプトで実現可能でしょうか? 基本的には、シェルスクリプトの先頭で、ある資源のロックを行い、終了時にロックの解放ができれば、その仕組みは実現可能と考えています。 (シェルの異常終了時は、ロックが自動的に解放されることが望ましい) 上記のようなことをシェル(bash)で実現可能でしょうか。 bash単独での方法、もしくはbashからperl,C言語作成の実行モジュールを呼び出す方法でもかまいません。 (ちなみにperl(もしくはC言語作成のモジュール)単独では実現可能なことはわかっています)

  • bashシェルスクリプトで変数を使う

    bashシェルスクリプト内で変数を使いたいです。 Linux内の設定ファイルを参考に、 ・変数名=その内容、で設定 ・${変数名} 、で呼び出す だと判断し、以下のように使っています。 #!/bin/bash WORK=/home/aaa/ cd ${WORK} その後検索したところ、 「呼び出すには、$変数名 のように記述する」との説明を見かけ、 実際$の後に変数名を付けるだけでも認識したのですが、 { }は付けても付けなくてもよいのでしょうか。 { }が必要な場合もあるのでしょうか。

  • コマンド

    以下のシェルスクリプトをパイプ等をつかって1行のコマンドで簡潔に書きたいとき、どう書けばいいでしょうか? $ ./test.sh src dst -- test.sh ---------------- #! /bin/bash src=$1 dst=$2 for i in $(cat ./files) do  何かのコマンド $i $1 $2; done; これを1行のコマンドで書くとしたら??

  • bashのシェルスクリプトの書き方

    macos x 10.5.5です。 あるコマンドを実行すると"y/n"を聞いてきます。コマンドラインから実行した場合は、単純にキーボードから"y"などと入力すれば済むわけですが、これをbashのシェルスクリプトでやる場合はどう書けば良いのでしょうか。尚、"y/n"に対する応答(キー入力)は常に"y"で構いません。 >hoge delete file1 -- hogeというコマンドを実行 >Are you sure ? ( enter y/n ) -- hogeが確認を要求 >y -- キーボードからyを入力 よろしくお願いします。

  • Linuxシェルスクリプトを新しいコマンドにしたい

    Linux初級者です。よろしくお願いします。 OSにFedora Core 10, シェルにtcshを使用しています。 よく使用するコマンドを、まとめて一括で実行するように、 新しいコマンドを作成したくて、次のようなことをしていたのですが (1)ホームディレクトリにmybinというディレクトリを作成してPATHを通す。 (2)newbin1という以下の内容のシェルスクリプトを作成して、~/mybinに置いておく。 ================================== #!/bin/tcsh -f date #実行コマンド例1 echo $PATH #実行コマンド例2 ================================== (3)chmodコマンドでファイルに実行権限を与える。 上記のような方法で、作成したシェルスクリプト(newbin1)を PATHの通ったディレクトリ(~/mybin)に置いて、 > newbin1 とコマンドを呼び出しても、 "newbin1: コマンドが見つかりません" というエラーになってしまいます。 > which newbin1 とすると、ちゃんとファイルのパスが表示されるのですが、 *********************************************************** 自分で作成したシェルスクリプト(newbin1)を、 新しいコマンドとして認識させるにはどのようにすればよいのでしょうか。 また、そもそもシェルスクリプトを新しいコマンドにすることが 不可能だったりするんでしょうか? ************************************************************ 一括で実行したいコマンドが多い場合に、aliasで割り当てるのが大変なので、 できればaliasコマンドは使わずにできる方法を探しています。 基本的な質問かもしれませんが、よろしくお願い致します。

  • シェルスクリプト(sh)の関数の戻り値とtestコマンドによる判定の仕

    シェルスクリプト(sh)の関数の戻り値とtestコマンドによる判定の仕方が分かりません。 -------------------------------------------------- #!/bin/sh . GetYesNo.sh          #外部シェルスクリプトを読み込んで... GetYesNo $1           #このGetYesNoの戻り値は0か1を出力するようにする。 if[ ??? -eq 0 ]; then      #"???"の部分に何を入力すれば良いか分かりません。 echo "真(0)です。" else echo "偽(0以外)です。" fi -------------------------------------------------- 戻り値が0か1しか出力しない外部シェルスクリプトを読み込んで、その戻り値をtestコマンドを利用して、0か1のどちらかを判定して、それぞれの出力を出したいけれど、どうやって出来ますでしょうか。 色々な方法を試してみましたが、ダメでした。 上記のコードの書き間違いがあると思いますが、あったらご指摘をお願いします。

  • シェルスクリプトからコマンド存在検査をするには?

    シェルスクリプト内で「コマンド(コマンドラインツール)の存在検査」をする方法を伺っても宜しいでしょうか? testコマンドで実験してみましたが、残念乍ダメでした。 環境:Cygwin(bash)、WinXP Pro 全パッチあて 以上どうぞ宜しくお願い致します。