[英]Perl system call throws strange error
我剛剛編寫了一個Perl腳本,該腳本重新啟動了Linux服務器上的服務列表。 它旨在作為cron工作運行。 但是,當我執行腳本時,會不斷出現此錯誤;
root@www:~/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;
}
實際上,我會對kill_rogue_procs中@ids中的內容更加懷疑。 這是ps后跟grep的結果,因此,如果ps不返回任何結果或pid的長度不是5位數字,則可能會有假值。
這是錯誤的:
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) {
從您傳遞給此子項的內容來看,@ ids將始終包含單個數組引用,因此(標量@ids)將始終為true。 這也意味着您最終將類似以下內容的內容傳遞給sh
:
kill ARRAY(0x91b0768)
您想要類似的東西(如果arrayref為空,則沒有任何循環可循環):
my $ids = shift;
...
for my $pid (@$ids) {
kill SIGTERM => $pid;
或代替循環:
kill SIGTERM => @$ids;
同樣,也無需調用系統來殺死進程。
為此,我要添加最后一行,因此您不必grep grep進程本身:
sub get_pids_by_process {
my $proc = shift;
$proc =~ s/^(.)/[$1]/;
隨着sh
引發錯誤,我很確定system
的參數之一正在擴展到意外的地方。 我會在將所有參數傳遞給系統之前進行快速調試,以打印所有參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.