これはFreeBSDに関するものです:
#uname -a
FreeBSD gw-mail 10.2-RELEASE FreeBSD 10.2-RELEASE #0 r286666: Wed Aug 12 19:31:38 UTC 2015 [email protected]:/usr/obj/usr/src/sys/GENERIC i386
インターネットが正しく機能しない場合は、インターネットに再接続するためにルートシェルで実行できるスクリプトを作成しました。これはケースごとに実行される2つの部分で構成されており、これらの部分は単純で強力な再接続を達成するために単一パスでは実行されません。
- つまり、アクティブな接続があるがpingがない場合、接続は切断されます。
- 接続がない場合は接続されます。
#vi /root/bin/ars-reconnect.pl
#!/usr/bin/env perl
my $file = '/var/log/ars.log';
my $tun = system("ifconfig tun0");
print "TUN: $tun\n";
my $ping = 1;
#/etc/rc.d/ppp status ; /etc/rc.d/ppp stop ; ifconfig ; sleep 5 ; /etc/rc.d/ppp status ; sleep 5 ; /etc/rc.d/ppp stop ; sleep 5 ; /etc/rc.d/ppp stop ; sleep 5 ; /etc/rc.d/ppp start ; sleep 5 ; ifconfig ; /etc/rc.d/ppp status ; ping -c 2 8.8.8.8
my %ppp = (
status=>system("/etc/rc.d/ppp status")
);
print "PPP(status): $ppp{status}\n";
if($tun == 0){
$ping = system("ping -c4 8.8.8.8");
print "PING: $ping\n";
if($ping != 0){
tailEcho("CONNECTED, but NO PING => Disconnecting", $file);
do{
$ppp{stop} = system("/etc/rc.d/ppp stop");
print "PPP(stop): $ppp{stop}\n";
$ppp{status} = system("/etc/rc.d/ppp status");
print "PPP(status): $ppp{status}\n";
}until($ppp{status} != 0);
}else{
print "ALREADY CONNECTED!!!\n";
}
}
if($tun != 0){
if($ping != 0){
tailEcho("NO CONNECTION => Reconnecting", $file);
do{
$ppp{start} = system("/etc/rc.d/ppp start");
print "PPP(start): $ppp{start}\n";
$ppp{status} = system("/etc/rc.d/ppp status");
print "PPP(status): $ppp{status}\n";
$ping = system("ping -c4 8.8.8.8");
print "PING: $ping\n";
}until($ppp{status} == 0);
}
}
sub tailEcho{
my ($str, $file) = @_;
if(open(my $L, ">>$file")){
print $L time.":\t$str\n";
close($L);
}
}
ルートタスクリストに以下を追加します。
#crontab-e
*/5 * * * * /root/bin/ars-reconnect.pl
次に、crontabで設定されているように5分後に起動することを確認するために、意図的に切断しました。
# /etc/rc.d/ppp 停止
待機後、接続は再接続されず、「/var/log/ars.log」(スクリプトに示すように)ログに新しい再接続エントリがありません。
手動で実行する場合:
# /root/bin/ars-reconnect.pl
再接続され、「/var/log/ars.log」は新しい再接続行を作成します。
# # tail /var/log/ars.log
1630330022: NO CONNECTION => Reconnecting
それはおそらくあなたのルートの最初のcrontabエントリなので、cronサービスを再起動する必要があるかもしれません。 :
# /etc/rc.d/cron 再起動
# /etc/rc.d/ppp 停止
その後、cronログを確認したところ、実際には要求されたように、5分ごとに上記のスクリプトを実行しようとしたことがわかりました。
#tail -n 20 /var/log/cron
Aug 30 14:15:00 gw-mail /usr/sbin/cron[15208]: (root) CMD (/root/bin/ars-reconnect.pl)
Aug 30 14:20:00 gw-mail /usr/sbin/cron[15212]: (root) CMD (/usr/libexec/atrun)
Aug 30 14:20:00 gw-mail /usr/sbin/cron[15213]: (root) CMD (/root/bin/ars-reconnect.pl)
Aug 30 14:22:00 gw-mail /usr/sbin/cron[15216]: (operator) CMD (/usr/libexec/save-entropy)
Aug 30 14:25:00 gw-mail /usr/sbin/cron[15229]: (root) CMD (/usr/libexec/atrun)
Aug 30 14:25:00 gw-mail /usr/sbin/cron[15230]: (root) CMD (/root/bin/ars-reconnect.pl)
Aug 30 14:30:00 gw-mail /usr/sbin/cron[15234]: (root) CMD (/usr/libexec/atrun)
Aug 30 14:30:00 gw-mail /usr/sbin/cron[15235]: (root) CMD (/root/bin/ars-reconnect.pl)
Aug 30 14:33:00 gw-mail /usr/sbin/cron[15239]: (operator) CMD (/usr/libexec/save-entropy)
Aug 30 14:35:00 gw-mail /usr/sbin/cron[15252]: (root) CMD (/usr/libexec/atrun)
Aug 30 14:35:00 gw-mail /usr/sbin/cron[15253]: (root) CMD (/root/bin/ars-reconnect.pl)
Aug 30 14:36:25 gw-mail crontab[15255]: (root) BEGIN EDIT (root)
Aug 30 14:37:04 gw-mail crontab[15255]: (root) END EDIT (root)
Aug 30 14:40:00 gw-mail /usr/sbin/cron[15259]: (root) CMD (/usr/libexec/atrun)
Aug 30 14:40:00 gw-mail /usr/sbin/cron[15260]: (root) CMD (/root/bin/ars-reconnect.pl)
Aug 30 14:44:00 gw-mail /usr/sbin/cron[15264]: (operator) CMD (/usr/libexec/save-entropy)
Aug 30 14:45:00 gw-mail /usr/sbin/cron[15278]: (root) CMD (/usr/libexec/atrun)
Aug 30 14:45:00 gw-mail /usr/sbin/cron[15279]: (root) CMD (/root/bin/ars-reconnect.pl)
Aug 30 14:50:00 gw-mail /usr/sbin/cron[15285]: (root) CMD (/usr/libexec/atrun)
Aug 30 14:50:00 gw-mail /usr/sbin/cron[15286]: (root) CMD (/root/bin/ars-reconnect.pl)
しかし、なぜ動作しないのですか?つまり、cronによって実行されたときになぜ再接続しないのですか?
一部の権限の問題が原因である可能性がありますが、cronログにエラーメッセージが表示されないため、どのように見つけることができますか?
答え1
私の考えは、環境があなたが思うものとは異なるということです。 Cronはほぼ空の環境でタスクを実行します。したがって、完全修飾パスを使用することは非常に良いです。また、私はすべてのスクリプトを明示的に説明するインタプリタを好む。通常、(crontabを使用するとき!).sh
スクリプトを起動するまで/bin/sh -c /mypath/myscript.sh
crontab
何が起こるかは、エントリがcrontab設定に従って実行されることですSHELL
(参照:スケジュールされたタスク(5))。これが/bin/sh
デフォルトです。これはいいえ環境が手動で実行されるときのように見えないようにするログインシェル。スクリプトでインタプリタを明示的に宣言せずに、代わりに次を使用します。環境いたずら。私の仮説は、環境が予想したものと同じではないということです。
次に、次のようにします(を使用してcrontab -e
)。
*/5 * * * * /usr/bin/perl /root/bin/ars-reconnect.pl
追加のデバッグ情報を表示するには、すべての内容をファイルに出力します。
*/5 * * * * /usr/bin/perl /root/bin/ars-reconnect.pl >/root/crondebug.output 2>&1
cronjobの出力は通常メールで送信されますが、移動する部分が1つ少なくなるため、上記の作業は簡単になります。
これはスクリプトも更新する必要があることを意味します。
$ping = system("/sbin/ping -c4 8.8.8.8");
PATH
crontabファイルで設定できますが、ほとんどそうしません。デフォルト値はPATH
次のとおりです。10.2そして最新バージョン(/usr/local
追加)。