For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > December 2006 > $ARGV[0] breaks the script









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author $ARGV[0] breaks the script
Gregory Machin

2006-12-14, 6:59 pm

hi
the script will not work if I use $ARGV[0] but works 100% if I hard
code the $input variable;
what have i missed ?

#!/usr/bin/perl

# if your prgram has the string "grep" in the name or in the path
# this program won't work.
use strict;
use warnings;

my $line;
my $input;

$input=$ARGV[0]; #$input="httpd";
chomp $input;
open PROS, "ps -ef|grep $input |";

while ($line = <PROS> ){
unless ($line =~ m/grep/){
print "$input is running\n";
exit;
}
}

print "$input isn't running\n";
exec "/etc/init.d/$input restart &";

Many thanks

--
Gregory Machin
gregory.machin@gmail.com
www.linuxpro.co.za
Paul Lalli

2006-12-14, 6:59 pm

Gregory Machin wrote:
> the script will not work if I use $ARGV[0] but works 100% if I hard
> code the $input variable;
> what have i missed ?


You've missed telling us what "not works" means. You've also missed
telling us exactly what you put on the command line to make it "not
work".

Paul Lalli

D. Bolliger

2006-12-14, 6:59 pm

Gregory Machin am Donnerstag, 14. Dezember 2006 13:24:
> hi


Hi Gregory

> the script will not work


"Not work?" :-)

> if I use $ARGV[0] but works 100% if I hard
> code the $input variable;
> what have i missed ?


You can give anything as cmd line argument, and the script will tell you that
it is not running, because of

a) open PROS, "ps -ef|grep $input |";
combined with
b) unless ($line =~ m/grep/){...}

This script is running as root... that makes it even more important to check
user provided data, what exactly is executed in the shell, and what binaries
are called.

- use absolute paths for binaries (ps and grep in this case)
- make sure that $input only contains ascii characters
for example, in this case, only a to z:

my ($input) = $ARGV[0]=~/([a-z]{,16})/; # untested
die unless $input;

btw: /etc/init.d/grep start ???

This is a hint to also check if $input corresponds to a binary
in /etc/init.d at the beginning of the script :-)

This would solve the grep-not-allowed/script-uses-grep-and-does-not-work
problem :-)

What about also using /etc/init.d/some_daemon status and check if this
information is in sync with the ps output (it isn't always, and the restart
could therefore fail - what you don't test)

hope this helps

Dani

> #!/usr/bin/perl
>
> # if your prgram has the string "grep" in the name or in the path
> # this program won't work.
>
> use strict;
> use warnings;
>
> my $line;
> my $input;
>
> $input=$ARGV[0]; #$input="httpd";
> chomp $input;
> open PROS, "ps -ef|grep $input |";
>
> while ($line = <PROS> ){
> unless ($line =~ m/grep/){
> print "$input is running\n";
> exit;
> }
> }
>
> print "$input isn't running\n";
> exec "/etc/init.d/$input restart &";
>
> Many thanks
>
> --
> Gregory Machin
> gregory.machin@gmail.com
> www.linuxpro.co.za

Gregory Machin

2006-12-15, 7:59 am

Hi thanks for looking at the script..

Just to clarify, the scipt runs perfectly if $input it hardcoded eg
$input="httpd".
thus if the process is running then it exits, if the process is not
running then it exicutes
exec "/etc/init.d/$input restart &";

But if I use $input=$ARGV[0] to give the process name from the command
line, it runs as if the process is running if if I have stoped/killed
it..

the only reason for this is that there is a hidden character, but
where is it comming from ?



On 12/14/06, D. Bolliger <info@dbolliger.ch> wrote:
> Gregory Machin am Donnerstag, 14. Dezember 2006 13:24:
>
> Hi Gregory
>
>
> "Not work?" :-)
>
>
> You can give anything as cmd line argument, and the script will tell you that
> it is not running, because of
>
> a) open PROS, "ps -ef|grep $input |";
> combined with
> b) unless ($line =~ m/grep/){...}
>
> This script is running as root... that makes it even more important to check
> user provided data, what exactly is executed in the shell, and what binaries
> are called.
>
> - use absolute paths for binaries (ps and grep in this case)
> - make sure that $input only contains ascii characters
> for example, in this case, only a to z:
>
> my ($input) = $ARGV[0]=~/([a-z]{,16})/; # untested
> die unless $input;
>
> btw: /etc/init.d/grep start ???
>
> This is a hint to also check if $input corresponds to a binary
> in /etc/init.d at the beginning of the script :-)
>
> This would solve the grep-not-allowed/script-uses-grep-and-does-not-work
> problem :-)
>
> What about also using /etc/init.d/some_daemon status and check if this
> information is in sync with the ps output (it isn't always, and the restart
> could therefore fail - what you don't test)
>
> hope this helps
>
> Dani
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>
>



--
Gregory Machin
gregory.machin@gmail.com
www.linuxpro.co.za
D. Bolliger

2006-12-15, 7:59 am

Gregory Machin am Freitag, 15. Dezember 2006 14:05:
> On 12/14/06, D. Bolliger <info@dbolliger.ch> wrote:

[reordered]
[color=darkred]
[color=darkred]
[color=darkred]
> Hi thanks for looking at the script..
>
> Just to clarify, the scipt runs perfectly if $input it hardcoded eg
> $input="httpd".
> thus if the process is running then it exits, if the process is not
> running then it exicutes
> exec "/etc/init.d/$input restart &";


Hm, possibly I overlooked something, misinterpreted my tests (with modified
code), and guessed wrong. At the moment I have no time to look further at it,
so just a small tip:

> But if I use $input=$ARGV[0] to give the process name from the command
> line, it runs as if the process is running if if I have stoped/killed
> it..
>
> the only reason for this is that there is a hidden character, but
> where is it comming from ?


What hidden character is it? I think it's not a line end character \r, \n,
^M... (you chomp())

What results when you print out $input and the cmdline to be executed like
this, to see the string between '<' and '>':

warn "<$whatever_to_print>"; ?

Dani

P.S.: Please post inline :-)
Mumia W.

2006-12-15, 6:59 pm

On 12/14/2006 06:24 AM, Gregory Machin wrote:
> hi
> the script will not work if I use $ARGV[0] but works 100% if I hard
> code the $input variable;
> what have i missed ?
>
> #!/usr/bin/perl
>
> # if your prgram has the string "grep" in the name or in the path
> # this program won't work.
> use strict;
> use warnings;
>
> my $line;
> my $input;
>
> $input=$ARGV[0]; #$input="httpd";
> chomp $input;
> open PROS, "ps -ef|grep $input |";
>
> while ($line = <PROS> ){
> unless ($line =~ m/grep/){
> print "$input is running\n";
> exit;
> }
> }
>
> print "$input isn't running\n";
> exec "/etc/init.d/$input restart &";
>
> Many thanks
>


Perhaps it would be easier to keep the grepping outside of the ps command:

my $input = $ARGV[0];
my @cmds = grep /\Q$input\E/, qx{ ps -eo '%c' };
if (@cmds < 1) {
... do something ...
}



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com