3

I am trying to navigate to a directory where I have my function stored which I need to use in my script for result generation. But I am stuck because Perl is not able to understand my syntax for function location (with whitespaces).

Here is my code:

$path ="D:\\AVI MEHENWAL\\PERL\\SCRIPTS\\PROJECTS\\SnmpCheck";

$snmpwalk = `$path\\SnmpWalk.exe -q -t:60 -r:$ip -v:2c -c:$comm -os:1.3.6.1.2.1.1 -op:1.3.6.1.2.1.1.9`;
print "$snmpwalk";

where SnmpWalk is my function located at path as in variable $path.

Perl returns following error at runtime:

D:\AVI MEHENWAL\PERL\SCRIPTS\PROJECTS\SnmpCheck>perl perl_snmpwalk_v2.0.pl
'D:\AVI' is not recognized as an internal or external command,
operable program or batch file.

How can I fix this problem?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
avimehenwal
  • 1,502
  • 3
  • 21
  • 30

5 Answers5

6

With judicious use of the correct quotation marks, this can be tidied up a lot. Backslashes within single quotes don't need escaping unless they are the last character in the string, and double quotes need only be escaped if they are also used as the string delimiter. It is also (almost certainly) wrong to put $snmpwalk in quotes when you print it.

my $path = 'D:\AVI MEHENWAL\PERL\SCRIPTS\PROJECTS\SnmpCheck';

my $snmpwalk = `"$path\\SnmpWalk.exe" -q -t:60 -r:$ip -v:2c -c:$comm -os:1.3.6.1.2.1.1 -op:1.3.6.1.2.1.1.9`;

print $snmpwalk;
Borodin
  • 126,100
  • 9
  • 70
  • 144
5

In Perl, q{string} can be used instead of 'string' (mnemonic single quote), and qq{string} instead of "string" (mnemonic double quote). Double quote evaluates variables and backslashes, while single quite does not. Also, qx{cmd} can be used instead of backticks in `cmd` (mnemonic quote and execute).

Using these constructs makes it much easier to escape strings in situations like yours:

my $snmpwalk = q{"D:\AVI MEHENWAL\PERL\SCRIPTS\PROJECTS\SnmpCheck\snmpwalk"};
my $result = qx{$snmpwalk -q -t:60 -r:$ip -v:2c -c:$comm -os:1.3.6.1.2.1.1 -op:1.3.6.1.2.1.1.9};
print $result;

Also note that even under Windows, you can use forward slashes (/) in a path. It works just fine as long as you use full path for executable.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mvp
  • 111,019
  • 13
  • 122
  • 148
4

On Linux/OS X, escape the whitespace with a \. On Windows, use quotes around the path.

Linux/OS X:

$escapedPath ="D:\\AVI\ MEHENWAL\\PERL\\SCRIPTS\\PROJECTS\\SnmpCheck";

Windows:

$escapedPath ="\"D:\\AVI MEHENWAL\\PERL\\SCRIPTS\\PROJECTS\\SnmpCheck"\";

Also look here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
asgoth
  • 35,552
  • 12
  • 89
  • 98
1

It is not Perl that is not understanding your path, it is cmd (the Windows shell). I think that by adding some quotes around your path will solve this issue. Try the following not so elegant hack:

$executable ="\"D:\\AVI MEHENWAL\\PERL\\SCRIPTS\\PROJECTS\\SnmpCheck\\SnmpWalk.exe\"";

$snmpwalk = `$executable -q -t:60 -r:$ip -v:2c -c:$comm -os:1.3.6.1.2.1.1 -op:1.3.6.1.2.1.1.9`;
print "$snmpwalk";
ikegami
  • 367,544
  • 15
  • 269
  • 518
Tudor Constantin
  • 26,330
  • 7
  • 49
  • 72
  • 3
    It's not a hack; it's actually what you have to do. – ikegami Jan 02 '13 at 14:03
  • it was a hack in the first draft, because the first quote was added in the first line and the second, in the second line. Also, the solution can be further beautified by using `'` instead of the surrounding quotes, getting away the need to escape the backslashes – Tudor Constantin Jan 02 '13 at 16:37
  • 1
    Double-quotes are only used to escape the spaces when running the command. They are not part of the executable path itself. So that's strange to put them in the variable named `$executable`. For that reason, Borodin's answer is better. – dolmen Jan 02 '13 at 23:30
0

I used this to examine the contents of a .jar file from within Perl running on Cygwin:

#!/bin/perl

$file = q{"C:\cygwin\home\lylez\Hadoop\hadoop-2.x\hadoop-2.2.0\share\hadoop\yarn\hadoop-yarn-api-2.2.0.jar"};
$path = '/cygdrive/c/Program Files/Java/jdk1.7.0_45/bin';

@result = qx{"$path\\jar" -tf $file 2>&1};

for my $result ( @result )
{
    chomp $result;
    print $result, "\n";
}
Lyle Z
  • 1,269
  • 10
  • 7