LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   perl: Context or Syntax (https://www.linuxquestions.org/questions/programming-9/perl-context-or-syntax-773964/)

merana 12-07-2009 06:53 AM

perl: Context or Syntax
 
Hi Everyone!

I am trying to figure out a very odd issue. I am trying to run a perl script remotely over an ssh session on a Solaris box (SunOS peso 5.9 Generic_122300-09 sun4u sparc SUNW,Sun-Fire-880) with perl (v5.6.1 built for sun4-solaris-64int). The process is that the monitoring box (Zenoss) logs in to the target solaris host over ssh with /bin/sh as it's default shell. Then it runs the perl script.

When I walk through this process, I log into the monitoring box and then su to the monitoring process user. Then I make the ssh connection to the target solaris host as the monitoring user. I then run the command to the perl script and I get an output as expected. However, when I run it from the application I get a command not found error. I thought that perhaps when the monitoring app starts its session that it maybe trying to run the script prefaced with another shell like:

/bin/sh /usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"

When I try to run it that way I get the following error:

$ /bin/sh /usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"
/usr/local/zenoss/libexec/check_pp1.pl: my: not found
/usr/local/zenoss/libexec/check_pp1.pl: syntax error at line 5: `\./' unexpected

I understand that the 'my' statement is a native function and it does work if I just run the command without the extra shell preface:

$ /usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"
peso PowerPath 2 Dead Paths Detected

The script looks like this:

Code:

#!/usr/bin/perl


my $hostname = `/bin/hostname`;
if ( $hostname =~ /^(.+?)\./ ) {
  $hostname = $1;
}
chomp $hostname;

if ( &check() ) {
  print "$hostname\tPowerPath\t0\tAll Paths Alive\n";
} else {
  print "$hostname\tPowerPath\t2\tDead Paths Detected\n";
}


sub check {
  my ( $status );
  $status = 1;
  open (IN, "/etc/powermt display dev=all |");
  while (<IN>) {
    $status = 0 if ( /dead/ );
  }
  close IN;
  return $status;
}

So the question is why the command fails when run under a sub-shell...

Anyone?

Thanks in advance.

Sergei Steshenko 12-07-2009 07:10 AM

Quote:

Originally Posted by merana (Post 3782616)
Hi Everyone!

I am trying to figure out a very odd issue. I am trying to run a perl script remotely over an ssh session on a Solaris box (SunOS peso 5.9 Generic_122300-09 sun4u sparc SUNW,Sun-Fire-880) with perl (v5.6.1 built for sun4-solaris-64int). The process is that the monitoring box (Zenoss) logs in to the target solaris host over ssh with /bin/sh as it's default shell. Then it runs the perl script.

When I walk through this process, I log into the monitoring box and then su to the monitoring process user. Then I make the ssh connection to the target solaris host as the monitoring user. I then run the command to the perl script and I get an output as expected. However, when I run it from the application I get a command not found error. I thought that perhaps when the monitoring app starts its session that it maybe trying to run the script prefaced with another shell like:

/bin/sh /usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"

When I try to run it that way I get the following error:

$ /bin/sh /usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"
/usr/local/zenoss/libexec/check_pp1.pl: my: not found
/usr/local/zenoss/libexec/check_pp1.pl: syntax error at line 5: `\./' unexpected

I understand that the 'my' statement is a native function and it does work if I just run the command without the extra shell preface:

$ /usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"
peso PowerPath 2 Dead Paths Detected

The script looks like this:

Code:

#!/usr/bin/perl


my $hostname = `/bin/hostname`;
if ( $hostname =~ /^(.+?)\./ ) {
  $hostname = $1;
}
chomp $hostname;

if ( &check() ) {
  print "$hostname\tPowerPath\t0\tAll Paths Alive\n";
} else {
  print "$hostname\tPowerPath\t2\tDead Paths Detected\n";
}


sub check {
  my ( $status );
  $status = 1;
  open (IN, "/etc/powermt display dev=all |");
  while (<IN>) {
    $status = 0 if ( /dead/ );
  }
  close IN;
  return $status;
}

So the question is why the command fails when run under a sub-shell...

Anyone?

Thanks in advance.

Your command line seems to be wrong - it should be more or less like

Code:

/bin/sh -c '/usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"'
.

Or even

Code:

/bin/sh -c 'perl -w /usr/local/zenoss/libexec/check_pp1.pl -r "All paths alive"'
,
but try the first suggestion first.

merana 12-07-2009 07:46 AM

Thanks for the initial response Sergei. I tried them both and got the following:

root@pennynew:/# /bin/sh -c '/usr/local/zenoss/libexec/check_pp.pl -r "All paths alive"'
pennynew PowerPath 2 Dead Paths Detected

root@pennynew:/# /bin/sh -c 'perl -w /usr/local/zenoss/libexec/check_pp.pl -r "All paths alive"'
pennynew PowerPath 2 Dead Paths Detected

So those both worked formatted as shown. Now I just need to figure out how Zenoss is passing the command back to the remote machine to see if it's having a syntax issue. I'll use your suggestions as a reference.

Thanks!

Sergei Steshenko 12-07-2009 07:57 AM

Quote:

Originally Posted by merana (Post 3782662)
Thanks for the initial response Sergei. I tried them both and got the following:

root@pennynew:/# /bin/sh -c '/usr/local/zenoss/libexec/check_pp.pl -r "All paths alive"'
pennynew PowerPath 2 Dead Paths Detected

root@pennynew:/# /bin/sh -c 'perl -w /usr/local/zenoss/libexec/check_pp.pl -r "All paths alive"'
pennynew PowerPath 2 Dead Paths Detected

So those both worked formatted as shown. Now I just need to figure out how Zenoss is passing the command back to the remote machine to see if it's having a syntax issue. I'll use your suggestions as a reference.

Thanks!

Syntax issues are reported to stderr.

And your script - as any Perl script - should have at least

-w

in the interpreter path and

Code:

use strict;
as the first statement in code.

chrism01 12-08-2009 12:17 AM

As per Sergei, then you can make the Perl prog executable and drop the 'perl -w' part of the invocation.


All times are GMT -5. The time now is 07:27 PM.