@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

プロンプトとcronでの実行結果の違い

1
投稿者投稿内容
やいば
常連さん
会議室デビュー日: 2002/06/21
投稿数: 30
お住まい・勤務地: 神奈川県/東京都
投稿日時: 2002-07-23 12:15
こんにちは、スーツを気分で着てくるやいばです。今日は暑い!

qmail連載を参考にし、analog.shを/usr/local/qmailanalog/bin以下に置き、
cronの設定をして起動したところ、毎回同じメールが届いてしまいます。

コード:
-----------Result of zoverall------------
Basic statistics

qtime is the time spent by a message in the queue.

ddelay is the latency for a successful delivery to one recipient---the
end of successful delivery, minus the time when the message was queued.

xdelay is the latency for a delivery attempt---the time when the attempt
finished, minus the time when it started. The average concurrency is the
total xdelay for all deliveries divided by the time span; this is a good
measure of how busy the mailer is.

Completed messages: 0

Total delivery attempts: 0

-----------Result of zddist------------
Distribution of ddelays for successful deliveries

Meaning of each line: The first pct% of successful deliveries
all happened within doneby seconds. The average ddelay was avg.

doneby  avg  pct

-----------Result of zdeferrals------------
Reasons for deferral

One line per reason for deferral. Information on each line:
* del is the number of deliveries that ended for this reason.
* xdelay is the total xdelay on those deliveries.

del  xdelay  reason


実行しているスクリプト群は、zoverall,zddist,zdeferralsの3つで、これを
プロンプト上から実行させると、Completed messagesの部分から下にログを
解析した結果が表示されるのですが、cronにて動作させるとそれがありません。

プロンプトとcronでの実行結果は何か違いがあるのでしょうか。
cronもroot権限で実行させていますし‥。

何か良い解決方法をお持ちの方がいらっしゃいましたら、ご教授願います。


_________________
+ やいば -
- http://wire.cside.to/ +
ふじい
大ベテラン
会議室デビュー日: 2002/05/07
投稿数: 123
お住まい・勤務地: 東京
投稿日時: 2002-07-24 11:21
こんにちは、藤井と申します。

引用:

やいばさんの書き込み (2002-07-23 12:15) より:

実行しているスクリプト群は、zoverall,zddist,zdeferralsの3つで、これを
プロンプト上から実行させると、Completed messagesの部分から下にログを
解析した結果が表示されるのですが、cronにて動作させるとそれがありません。

プロンプトとcronでの実行結果は何か違いがあるのでしょうか。
cronもroot権限で実行させていますし‥。

何か良い解決方法をお持ちの方がいらっしゃいましたら、ご教授願います。



その記事の内容は試していないのですが、cronに関してはプロンプトと違いますよ。

実行するユーザーが違いますよね。なので、ホームディレクトリや環境変数が違うんです。

もうわかると思いますが、基本的には、

・必要なら環境変数を指定する
・フルパスで指定するか、そのまえにcd 対象のディレクトリとしておく

という手順が必要です。

たとえば、/home/sample/sample.sh というスクリプトをLOCALE=Cで、毎日5時30分に実行するときは

$ crontab -e
LOCALE=C
30 5 * * * /home/sample/sample.sh

または、

$ crontab -e
LOCALE=C
30 5 * * * cd /home/sample && ./sample.sh

たしか、こんな感じかな?
やいば
常連さん
会議室デビュー日: 2002/06/21
投稿数: 30
お住まい・勤務地: 神奈川県/東京都
投稿日時: 2002-07-24 11:51
藤井さん、お返事有り難うございます。

引用:

ふじいさんの書き込み (2002-07-24 11:21) より:
実行するユーザーが違いますよね。なので、ホームディレクトリや環境変数が違うんです。

もうわかると思いますが、基本的には、

・必要なら環境変数を指定する
・フルパスで指定するか、そのまえにcd 対象のディレクトリとしておく

という手順が必要です。


スクリプトの中に、環境変数はexportしてありますし、cronには実行スクリプトを
フルパスで指定してあります。知識が足らないのもあり、「ひょっとするとexport
がマズいのでは??」と思ってecho $PATHで出てきたrootの環境変数をanalog.shに
書き加えてみても結果は同様でした。

ほかに設定すべき環境変数とかがあるのでしょうか‥。
setコマンドで出てきたものは知らない変数ばかりで、これのどれを参照すれば
よいのか分かりません。PATH以外に、analog.sh実行に必要な変数があるかなぁ‥

_________________
+ やいば +
+ jk@lunar.to +

[ メッセージ編集済み 編集者: やいば 編集日時 2002-07-24 11:52 ]
ふじい
大ベテラン
会議室デビュー日: 2002/05/07
投稿数: 123
お住まい・勤務地: 東京
投稿日時: 2002-07-24 13:23
こんにちは、藤井です。

引用:

やいばさんの書き込み (2002-07-24 11:51) より:

スクリプトの中に、環境変数はexportしてありますし、cronには実行スクリプトを
フルパスで指定してあります。知識が足らないのもあり、「ひょっとするとexport
がマズいのでは??」と思ってecho $PATHで出てきたrootの環境変数をanalog.shに
書き加えてみても結果は同様でした。

ほかに設定すべき環境変数とかがあるのでしょうか‥。
setコマンドで出てきたものは知らない変数ばかりで、これのどれを参照すれば
よいのか分かりません。PATH以外に、analog.sh実行に必要な変数があるかなぁ‥



すみません、外してましたか。
ちょっとその連載を見てみます。もう少しお待ちを・・・。

そのまえに、よくありがちなパターンを書いておきますと、

・書き込みや実行の権利がなかった
・スクリプト自体は絶対パスで指定しているが、その内部のスクリプト自体に相対パスが有り、そこでひっかかる

というのがあります。2番目が結構厄介で、僕もその為に何回か書き直したことがあります。
ふじい
大ベテラン
会議室デビュー日: 2002/05/07
投稿数: 123
お住まい・勤務地: 東京
投稿日時: 2002-07-24 13:39
こんにちは、藤井です。最初から連載を見てから、答えればよかったです。すみません。

ところで、見た感じ特に問題がなさそうです。しかし実際に動いていないわけですから、考えられるとすれば、PATHにたとえばanalogをインストールしたパスが入ってないくらいしか思いつきません。

これではどうしようもないので、これを試してもらえませんか?

連載のcronをどうさせる部分ですが、

# crontab -e
(以下が追加分)
01 0 * * * /usr/local/qmailanalog/bin/analog.sh 2>/dev/null

の部分を

# crontab -e
(以下が追加分)
01 0 * * * /usr/local/qmailanalog/bin/analog.sh 2>/tmp/qmailanalog-error.log

とかにして、エラーメッセージを見るのがいちばんでしょう。もしそれで解決法がわかれば、解決していただいて、それでもうまく動かない場合はエラー内容を載せていただけると助かります。

あと蛇足ですが、このような場合、STDINから受け取った文字列を、改行して、タイムスタンプを追加するようなスクリプト適当に書いておいて、
01 0 * * * /usr/local/qmailanalog/bin/analog.sh 2>>/tmp/hogehoge.sh
などとし、それをtail -f でみるとデバッグラクですよ。
やいば
常連さん
会議室デビュー日: 2002/06/21
投稿数: 30
お住まい・勤務地: 神奈川県/東京都
投稿日時: 2002-07-24 14:41
解決しました! 行った手順は以下のとおりです。


1. crontab -eでanalog.shの行の 2>/dev/null を 2>/tmp/error.logに書き換え
2. cronにて実行させたところ、エラーログの中にリスト末尾記載の2行を発見
3. which tai64n2taiでtai64n2taiのパスを特定
4. /usr/local/bin以下にtai61n2taiが存在したので、パスをanalog.sh内のPATHに記述
5. ログを解析したメールが到着

コード:

/usr/local/qmailanalog/bin/analog.sh: tai64n2tai: command not found
Bad line: ''



という結果になりました。
ありがとうございます! 本当に助かりました。しかし腑に落ちないのは、rootの
PATHには/usr/local/binがあり、それをanalog.shのexport行に追記した場合
でも正常に動作しなかったのに‥という点です。ですがこれは、何か見落として
いた部分が他にあったのでしょう。

引用:

ふじいさんの書き込み (2002-07-24 13:39) より:
あと蛇足ですが、このような場合、STDINから受け取った文字列を、改行して、タイムスタンプを追加するようなスクリプト適当に書いておいて、
01 0 * * * /usr/local/qmailanalog/bin/analog.sh 2>>/tmp/hogehoge.sh
などとし、それをtail -f でみるとデバッグラクですよ。


これを今からちょっとやってみたいと思います。
しかしこのスレッドも、鶴長さんに見てもらわなければ‥(行番号なしのファイルを
ダウンロードしたのですが、それにはexportの行に/usr/local/binがありません
でしたので)。

_________________
+ やいば +
+ jk@lunar.to +

[ メッセージ編集済み 編集者: やいば 編集日時 2002-07-24 14:47 ]
ふじい
大ベテラン
会議室デビュー日: 2002/05/07
投稿数: 123
お住まい・勤務地: 東京
投稿日時: 2002-07-25 16:52
こんにちは、藤井です。よかったっすね。

引用:

ありがとうございます! 本当に助かりました。しかし腑に落ちないのは、rootの
PATHには/usr/local/binがあり、それをanalog.shのexport行に追記した場合
でも正常に動作しなかったのに‥という点です。ですがこれは、何か見落として
いた部分が他にあったのでしょう。



それって、bashをお使いなら、.bash_profileに記述されてません? それはログインしたときに実行されるので、通常にログインすると実行されるので問題なし、cronでやるときはログインシェルとして起動されていないので実行されず、環境変数を設定されないということです。詳しくは、こちら。

http://www.atmarkit.co.jp/flinux/rensai/linuxtips/168bpronrc.html

またまた蛇足ですが、
2>/dev/null
の様な記述は、ご存知の通り、エラー出力を捨ててます。動作が確認できるまではしないほうがいいでしょう。

今回やいばさんが悩んだ一番の原因が、どういうエラーが出ているのか特定できていなかったところです。エラーメッセージを見ればすぐにわかったと思います。

また、いったい何時のエラーなのかというのも重要です。なので、タイムスタンプはあったほうが格段に使いやすくなります。

たとえば、簡単に作ってみると

#!/usr/bin/perl -w
use strict;
my $date = `date`;
chomp($date);
print "\n[ " . $date . " ] \n";
while (<>) {
print;
}

一行目の「#!/usr/bin/perl」は which perl の出力に変えてくださいね。
これをlog.plとすると

30 5 * * * /path/to/sample.sh 2> /path/to/log.pl >> /path/to/error.log
とかできるのでは?(未検証)

もっとましなコード書いてくださいね(笑)。あくまでもサンプルなので。

自分ではもっとましなの書いてますが、かなり自分の環境に決め打ちで書いているので、紹介できないです。
1

アイティメディアの提供サービス

ホワイトペーパー(TechTargetジャパン/閲覧には会員登録が必要です)

スキルアップ/キャリアアップ(JOB@IT)