Escaping pipe in perl - perl

I'm having some trouble with backtics and pipe in perl. I have following code:
my #arr_lsdev = `lsdev -C | grep inet | awk '{print \$1}'` ;
print Dumper #arr_lsdev ;
But I get following error:
sh[2]: 0403-057 Syntax error : `|' is not expected
I'm guessing it has something to with my escape commands. I have tried escaping the | but it still results in the same error.
OS: AIX
Shell: KSH

Notice that the error is on line 2. You are actually executing
my #arr_lsdev = `lsdev -C | grep inet
| awk '{print \$1}'` ;

You can reduce the number of pipes:
my #arr_lsdev = map {(split ' ')[0]} grep {/inet/} `lsdev -C`;

Related

quoting {print $NF} inside layers of single and double quotes?

Stuck trying to figure out how to single quotes withing single quotes within double quotes. Here's what I'm trying to do....
From perl, I want to run a system command that...
- does an ssh into a remote machine
- executes 'uptime' and then plucks the last field out of that (avg load last 15 min).
\#\!/usr/bin/env perl
my $cmd = "ssh othermachine 'uptime | awk '{print $NF}'' > local_file.dat";
system($cmd);
Of course this won't run ...
% ./try.pl
Missing }.
%
Missing "}" ??? Looks like it's interpreting the $NF} as a var? I tried escaping the {} chars with no luck. I tried escaping the $, no luck. I tried a space before the }, no luck but different msg (Undefined variable).
c-shell BTW and thanks in advance !
You want the following to be ssh's second argument:
uptime | awk '{print $NF}'
To do that, you simply placed single quotes around it. But that doesn't work because it contains single quotes.
You want to build a string that contains $NF, but you did it as follows:
"...$NF..."
That will place the value of (non-existent) Perl variable $NF in the string.
Do it step by step.
Static:
Remote command:
uptime | awk '{print $NF}'
Local command:
ssh othermachine 'uptime | awk '\''{print $NF}'\''' >local_file.dat
String literal:
my $local_cmd = q{ssh othermachine 'uptime | awk '\''{print $NF}'\''' >local_file.dat}
Dynamic:
use String::ShellQuote qw( shell_quote );
my $remote_cmd = q{uptime | awk '{print $NF}'};
my $local_cmd = shell_quote('ssh', 'othermachine', $remote_cmd) . ' >local_file.dat';
Use Net::OpenSSH and let it do the quoting for you:
use Net::OpenSSH;
my $ssh = Net::OpenSSH->new($othermachine,
remote_shell => 'tcsh');
$ssh->system({stdout_file => 'local_file.dat'},
'uptime', \\'|', 'awk', '{print $NF}')
or die "ssh command failed: " . $ssh->error;

How does ps aux | grep '[p]attern' exclude grep itself?

The title says it all. I've seen this idiom used alot instead of adding an additional grep -v grep in some ps pipeline. For example it could be used like this:
$ ps aux | grep '[f]irefox' | awk '{ print $8 }'
instead of
$ ps aux | grep 'firefox' | grep -v grep | awk '{ print $8 }'
It's super-convenient, but how does it work and why?
The pattern [f]irefox will not match the literal string [f]irefox. Instead it will match strings with exactly one char from the 1-character class [f], followed by irefox.

Perls system($command) returns other result than command on shell

I'm trying to fetch a version number from an xml-file on a remote machine. I do this via the Net::SSH::Perl cmd function. It looks something like this:
my ($version, $err, $exit) = $ssh->cmd("head -11 /some/path/to/the/file.xml | tail -1 | sed 's/<[^>]\+>//g' | xargs");
print Dumper $version;
What I'm trying to achieve with that is, to extract the number out of an XML-tag <version>2.6</version>
It works perfectly fine, when I use the cmd on a ssh-shell via PuTTy
user#remotemachine:~>head -11 /some/path/to/the/file.xml | tail -1 | sed 's/<[^>]\+>//g' | xargs
2.6
user#remotemachine:~>
However, Perl prints
$VAR1 = '<version>2.6</version>
';
Any ideas, why it's not working?
Edit: Obviously it has nothing to do with the Net::SSH::Perl-module, since
perl -e "system(\"head -11 /some/path/to/the/file.xml | tail -1 | sed 's/<[^>]\+>//g' | xargs\");"
Also prints
<version>2.6</version>
You are using double quotes. In double quotes, \ is special, so only + instead of \+ is passed to sed.
You can use the q() operator to avoid backslashing the backslash:
$ssh->cmd(q(head -11 /some/path/to/the/file.xml | tail -1 | sed 's/<[^>]\+>//g' | xargs));

Perl telnet command not sending every command

I have the following program below which telnets into another device and prints serial number and Mac address.
My problem is that for some reason if I send the command once it skips the first command and sends the second, but if I copy the same command twice it will send the command.
What is the correct way to send a command multiple commands successively?
Should the buffer be flushed after every command sent ?
My Env
Eclipse Ide
Ubuntu 12.10
perl 5, version 14, subversion 2 (v5.14.2)
Snippet of my code:
$telnet = Net::Telnet->new($remoteSystem);
$| = 1;
$telnet->buffer_empty();
$telnet->buffer_empty();
$result = $telnet->input_log($errorlog);
#$_ = "#lines";
#TSN =$telnet->cmd('export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2');
#TSN =$telnet->cmd('export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2');
#mac = $telnet->cmd('ifconfig | grep eth0 | cut -d" " -f 11');
print "#TSN AND #TSN #mac";
print FH "$remoteSystem\n";
print "Telnetting into $remoteSystem .\n"; # Prints names of the tcd
close(telnet);
}
foreach (#host) {
checkStatus($_);
}
OUTPUT That skips the first command:
bash-2.02 AND bash-2.02 ifconfig | grep eth0 | cut -d" " -f 11
00:11:D9:3C:6E:02
bash-2.02 #
bash-2.02 Telnetting into debug79-109 .
OUTPUT That works but I have to send the same command twice:
export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2
AE20001901E2FD1
bash-2.02 #
bash-2.02 AND export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2
AE20001901E2FD1
bash-2.02 #
bash-2.02 ifconfig | grep eth0 | cut -d" " -f 11
00:11:D9:3C:6E:02
bash-2.02 #
bash-2.02 Telnetting into debug79-109
Specify the command prompt in your call to cmd(), e.g.#TSN =$telnet->cmd('export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2', Prompt => 'bash-2.02 #');
Try opening a connection after creating a object for the module telnet
$telnet->open($host);
After which execute waitFor method:(waits until the pattern bash-2.02 # comes)
$telnet->waitFor(/^(bash-\d+.\d+ #)$/);
and then execute your commands , it would give you proper output.

syntax error near unexpected token `|' Perl code

I am trying to execute this in my perl script
my $command = `ps -p $pidnumber | wc -l`;
but when I run the script it show me something like this:
sh: -c: line 1: syntax error near unexpected token `|'
sh: -c: line 1: ` | wc -l'
Which would it may to be the error?
Does $pidnumber end with a new line? See the chomp function.
try print before execute the command, because $pidnumber may have something strange:
my $command_str = "ps -p $pidnumber | wc -l";
print $command_str, "\n";
my $command = qx!$command_str!;
as #mob said, use chomp if newline appears in the print sentence.
I agree with the other answers that an extra newline before the pipe is quite possibly the cause
But the command doesn't really need the pipe!
force the quoted command to return it's value as a list and then get the length of the list and you've got the wc -l "line count"
my $command_str = "ps -p $pidnumber";
my $linecount = () = qx!$command_str!;