2012-01-04 6 views
0

Linuxサーバーでサービスのリストを再起動するperlスクリプトを書いたばかりです。これは、cronジョブとして実行することを意図しています。スクリプトを実行すると、このエラーが発生します。Perlシステムコールで奇妙なエラーが発生する

[email protected]:~/scripts# ./ws_restart.pl 
    * Stopping web server apache2         [ OK ] 
sh: Syntax error: "(" unexpected 
    * Stopping MySQL database server mysqld       [ OK ] 
sh: Syntax error: "(" unexpected 

これを行うために使用されている呼び出しは、次のとおりです。

system("/etc/init.d/apache2 stop"); 
system("/etc/init.d/mysql stop"); 

必要であれば、私は、全体のスクリプトコードを貼り付けることができますが、私は、これが問題の原因であるとちょうどそれを停止する方法を知っておく必要があることを考え出しました。

アイデア?

ここにスクリプト全体があります。

#!/usr/bin/perl 

use strict; 
use warnings; 

use Data::Dumper; 

my $old_pids = {}; 
my $post_stop_ids = {}; 
my @services = qw/apache2 mysql solr/; 
my $app_dir = '/home/grip/apps/eventfinder'; 


# collect existing pids then kill services 
foreach my $service (@services) { 
    # gather up existing pids 
    $old_pids->{$service} = [ get_pids_by_process($service) ]; 

    # issue stop command to each service 
    set_service_state($service, 'stop'); 

    # attempt to regather same ids 
    $post_stop_ids->{$service} = [ get_pids_by_process($service) ]; 

    # kill any rogue ids left over 
    kill_rogue_procs($post_stop_ids->{$service}); 

    # give each kill time to finish 
    sleep(5); 
} 


# attempt to restart killed services 
foreach my $service (@services) { 
    # issue start command to each service 
    set_service_state($service, 'start'); 

    # Let's give each service enough time to crawl outta bed. 
    # I know how much I hate waking up 
    sleep(5); 
} 

# wait for it!...wait for it! :P 
# Pad an extra 5 seconds to give solr enough time to come up before we reindex 
sleep(5); 

# start the reindexing process of solr 
system("cd $app_dir ; RAILS_ENV=production rake reindex_active"); 

# call it a day...phew! 
exit 0; 

sub kill_rogue_procs { 
    my @ids = shift; 
    # check if we still have any rogue processes that failed to die 
    # if so, kill them now. 
    if(scalar @ids) { 
    foreach my $pid (@ids) { 
     system("kill $pid"); 
    } 
    } 
} 


sub set_service_state { 
    my ($proc, $state) = @_; 

    if($proc eq 'apache2') { 
    system("/etc/init.d/apache2 $state"); 
    } elsif($proc eq 'mysql') { 
    system("/etc/init.d/mysql $state"); 
    } elsif($proc eq 'solr') { 
    system("cd $app_dir ; RAILS_ENV=production rake sunspot:solr:$state"); 
    } 
} 


sub get_pids_by_process { 
    my $proc = shift; 

    my @proc_ids =(); 

    open(PSAE, "/bin/ps -ae | grep $proc |") || die("Couldn't run command"); 

    while(<PSAE>) { 
    push @proc_ids, $_ =~ /(\d{1,5})/; 
    } 

    close PSAE; 

    return @proc_ids; 
} 
+0

をあなたは 'perlの-e「システム("は/ etc/initのを試してみたらどうなりますか。 d/apache2 stop "); ''? –

+0

うまく動作します。私はコードを貼り付けます。 – Skittles

+0

その時点で$状態が分かりますか? –

答えて

3

実際、私はkill_rogue_procsの@idsに何が入っているのか疑問に思います。 psの結果がgrepであるため、psが結果を返さない場合、またはpidが5桁でない場合は、偽の値を持つ可能性があります。

+0

恐ろしい!ありがとう、ポール! :) – Skittles

1

shがエラーを上げているように、私はsystemへのパラメータの一つは、予想外の何かに展開されているかなり確信しています。クイックデバッグのためにシステムに渡す直前にすべてのパラメータを表示します。

+0

システムコールを変更してkillコマンドを/ bin/killとして呼び出そうとしましたが、それでもそれを止めませんでした。私が気づいたのは、存在しないピッドを殺そうとすると、あなたはこのshメッセージを受け取ります: "bash:kill:(31014) - そのようなプロセスはありません"。それはおそらく開かれている父親がどこからきているのだろうか? – Skittles

+0

@Skittlesは、「システムコールを変更する」という助言は与えられていませんでした。与えられたアドバイスはとても良かったので、それに従ってください。 – ikegami

3

これは間違っている:あなたはこのサブに渡しているのか、@idsは常に単一の配列参照を含んでいますので、(スカラー@ids)から

sub kill_rogue_procs { 
    my @ids = shift; 
    # check if we still have any rogue processes that failed to die 
    # if so, kill them now. 
    if(scalar @ids) { 

常にtrueになります。 (とにかく以上の配列リファレンスが空の場合、何もないのループ)

あなたが何かをしたい
kill ARRAY(0x91b0768) 

my $ids = shift; 
... 
for my $pid (@$ids) { 
    kill SIGTERM => $pid; 

またはその代わりにそれはまた次のshのようなものを渡してしまうことループ:

kill SIGTERM => @$ids; 

また、killにプロセスを呼び出す必要はありません。これに

あなたはgrepのプロセス自体をgrepしていないので、私は、最後の行を追加したい:

sub get_pids_by_process { 
    my $proc = shift; 
    $proc =~ s/^(.)/[$1]/; 
+0

これはすばらしいアドバイスです。私はまだそれらを試していませんが、最も確実にそれらを追加します。私がperlについて気に入っているのは、あなたが言語に慣れていくほど、同じ結果を達成するために必要なことです。私はperlの専門家ではありませんが、私はあなたのスクリプトから私の専門知識のレベルを測ることができると確信しています。これを共有してくれてありがとう。 – Skittles

+0

@runrig、あなたは答えからちょっと離れていたので、私はそれを追加しました。 – ikegami

関連する問題