プロが教える店舗&オフィスのセキュリティ対策術

こんにちは、ど素人なのにシェルスクリプト仕事で書かされ苦しんでます。
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コマンドで良い解決法ご教示願います。
情報が不足なら指摘いただいた物を追加いたします。

A 回答 (4件)

具体的にどのようなディレクトリ構成で、具体的にどのようなコードを書いて、具体的にどのようなエラーメッセージが出たんでしょう?



>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個程度出てきます。やはり全てのファイル名
をダブルパイプで連結しかありませんか?

補足日時:2007/04/06 18:24
    • good
    • 0

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で検索しながら
使えそうなコマンドを探して書いている状況です。

分かりにくい文章を丁寧に判読してくださりありがとうございます。
こちらの検討した仕様に考慮不足や補足情報が必要でしたら
ご指摘ください。

補足日時:2007/04/07 06:56
    • good
    • 0

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は何を判定してますか?

補足日時:2007/04/07 21:44
    • good
    • 0

>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部かのどちらかが実行されるわけです。

この回答への補足

ご回答ありがとうございます。

>$FLAGがtureかfalseかによって、最後のif文のthen部かelse部かのどちらかが実行されるわけです。

IF$FLAGってくっつけてもOKですか?IFと$間に空間がいるとか。
trueの場合最後のif文のthen部かelse部はthenの部分で、
falseのときはelseが実行されるんですね。

月曜日に会社へ行ってやってみます。
成功したら、とっても嬉しいです。
月曜の晩までお礼お待ちくださいませ。

補足日時:2007/04/08 00:38
    • good
    • 0
この回答へのお礼

こんばんは

本当に助かりました。
FOR文を使うのは気が付かなかったです。
ちゃんと動きました。

一つ疑問があって
シェル実行中に
下のメッセージが出るのですが
include .cshrc_Lx
これは何か設定がまずいのですか?

お礼日時:2007/04/09 18:02

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!