get output of execution perl - perl

Usually to get the output of a command I run from perl I use back tick
my $value = `pwd`;
How do I do it though if I need to insert a variable within the back ticks ``?

Text inside backticks is interpolated before it is passed to the operating system in the same way as text inside double quotes. So these statements all do what they look like they do:
$value = `$command`;
$value = `$someCommand $arg`;
$value = `$someOtherCommand #list`;
qx() is another way of running an external command and returning the output. If for some reason you don't want Perl to interpolate your command, you can run qx with the single-quote delimiter.
$value = qx'echo $PATH'; # shell's $PATH, not Perl's $PATH

You can just insert it. E.g.
my $dir = "/home"
my $text = `ls -l $dir`;
print $text;

my $hello = "world";
my $value = ` echo $hello `;
print $value;

Use qx() instead of backticks. Eg. my ($used, $dir); ($used) = qx(du -k $dir);

Related

How do you use the 7z test?

The directory of the file is defined.
I want to get the 'test' value using the 'test' command of 7z.
foreach $str0 (glob "*.zip"){
my $test = system( "7z t -y $str0");
print $test;
}
How can I get the '7z test' value?
Edit:
Do you mean to use qx instead of System?
Is it right that you meant it?
foreach $str0 (glob "*.zip"){
my $test = qx/7z t -y $str0/;
print $test;
}
or
foreach $str0 (glob "*.zip"){
my $test = `7z t -y $str0`;
print $test;
}
I tried both, but I can't get the 'test value'.
There are at least three ways to do this in Perl; the qx and backticks ways are basically the same thing, except with qx you have a choice of what delimiter to use to start/end the string. Using ' as the delimiter prevents variable interpolation.
The third way is using open to open a pipe to 7zip.
#with qx
my $test = qx/7z t -y $str0/;
#with backticks
my $test = `7z t -y $str0`;
#with open
open my $pipe, '-|', '7z', 't', '-y', $str0;
my $test = join "\n", readline $pipe;
close $pipe;

Perl hangs up on while loop

This code hangs up for some reason or just doesn't go any further when while (<>) { $file .= $_}; is queried. Why is that?
As soon as I start the code with the entered text does not happen more than that it outputs task1 and then it hangs.
Code:
#!/usr/bin/perl -w
use strict;
use JSON;
my $json = JSON->new->allow_nonref;
my $file = "";
print('task1');
while (<>) { $file .= $_ };
print('task2');
my $json_output = $json->decode( $file );
my ($c, $i, $cstr, $istr);
foreach my $cert (#$json_output) {
print('task3');
$i = $json_output->{i};
$c = $json_output->{c};
$istr = join("", map { sprintf("%02x",$_) } #$i);
$cstr = pack("C*", #$c);
open(F, ">$istr.der"); print F $cstr; close(F);
print('done.');
}
Output:
task1
This line
while (<>) { $file .= $_ };
is trying to read from a file specified on the command line, or if there isn't one, from standard input. If there isn't anything piped to standard input, then it sits waiting for you to type something at the keyboard.
So I'm guessing you didn't specify a file on the command line, and your program is sitting there waiting to get input from standard input.
Also, the easier way to read in the entire file to a single variable is like so:
my $file = do { local $/; <> };
See this article for other options.
How do you invoke your code? The <> operator means that it takes input from either all the files that you specify as arguments, or from standard input. If you call your script with no arguments, it will sit and wait for console input.
If you call it without arguments, try entering a few lines of text when it is "hanging", and then type Ctrl+D if you are on Linux, or Ctrl+Z on Windows. That should make the script work.

how to run a shell command in perl in backticks when command also has backticks

example.
$output= `eval `environment` ; echo $Variable` ;
i want to execute this command
eval `environment` ; echo $Variable
in a perl script.
$output= `eval `environment` ; echo $Variable` ;
Use the qx// form from the "Quote-like Operators":
my $output = qx{eval `environment` ; echo $Variable};
But that still probably wouldn't do what you want, since $Variable would be already evaluated and interpolated by Perl. To fix that:
# single quotes:
my $command = q{eval `environment` ; echo $Variable};
# and then execute it:
my $output = qx{$command};
Alternatively, a little hack:
my $output = qx'eval `environment` ; echo $Variable';
When the ' is used as the character to the quote-like operators, it inhibits the variable interpolation.
You may use Backtiks "here documents" - see Backtics sub section in man perlop for details. $ sign must be escaped if you want to avoid variable expansion by perl.
#!/usr/bin/perl
use strict;
use warnings;
my $output = <<`END`;
eval `environment` ; echo \$Variable
END
print $output;

Perl - Using backquotes missing output

Hello guys i need to capture the output of an external command, herefore I use backquotes.
However when the command reaches a newline the output is ommitted. Where $_ = AD
#lines = `"C:/Program Files/Veritas/NetBackup/bin/admincmd/bppllist" $_ -U"`
Test: test1
Test: test2
Test: test3
Test: test4
The actual output:
#lines
Test: test1
Test: test2
Thank you for your time.
print HTML "<h2 id='pol'>Policy Configuration\n</h2>" ;
#bpllist =`"$admincmd/bppllist.exe"` or die print "$admincmd/bppllist.exe not found or could not be executed";
foreach (#bpllist)
{
print HTML "<div><table class='table'>\n";
#lines = `"$admincmd/bppllist" $_ -U` or die print "$admincmd/bpplinfo $_ -U not found or could not be executed";
print HTML "\t<tr>\n\t<td><b>Policy name: <b></td><td>$_</td>\n\t</tr>\n" ;
foreach (#lines) {
chop;
($var, $value) = split(/:/,$_,2);
$var = "" if !defined($var);
$value = "" if !defined($value);
print HTML "\t<tr>\n\t<td>$var</td><td>$value</td>\n\t</tr>\n" ;
}
print HTML "</table></div>";
}
The output of #bpllist:
AD
Sharepoint
Echchange
Vmware
Here's how to capture the STDOUT & STDERR of a spawned process using backticks:
my $output = join('', `command arg1 arg2 arg3 2>&1`);
How it works has no dependence whatsoever on newlines in the output of command.
If you also need to send text to command's STDIN, then use IPC::Open3.
Cleaned your code up a bit. It works for me.
use strict;
use warnings;
use 5.10.0;
# something missing here to set up HTML file handle
# something missing here to set up $admincmd
print HTML q{<h2 id='pol'>Policy Configuration\n</h2>};
my #bpllist = `"$admincmd/bppllist.exe"`
or die "$admincmd/bppllist.exe not found or could not be executed\n";
for my $policy (#bpllist) {
print HTML q{<div><table class='table'>\n};
my #lines = `$admincmd/bpplinfo.exe $policy -U 2>&1`;
print HTML qq{\t<tr>\n\t<td><b>Policy name: <b></td><td>$policy</td>\n\t</tr>\n} ;
for my $pair (#lines) {
chomp($pair); # only remove newlines, not other characters
my ($var, $value) = split /:/, $pair, 2;
$var //= '';
$value //= '';
print HTML qq{\t<tr>\n\t<td>$var</td><td>$value</td>\n\t</tr>\n} ;
}
print HTML q{</table></div>};
}
Update 2
You appear to be doing this on windows?
I don't think the 2>&1 trick will work there.
Instead of using qx or backticks and then shell commands to redirect output, give the core module, IPC::Cmd, a try. In particular, its exportable function &run will conveniently capture both STDOUT and STDERR for you. From the synopsis:
### in list context ###
my( $success, $error_message, $full_buf, $stdout_buf, $stderr_buf ) =
run( command => $cmd, verbose => 0 );
Maybe the command send its output to stderr.
Try this:
my $output = `'command' -ARG -L 2>&1`;
regards,

How do I echo string with bash command more in Perl?

This is what I tried:
my $s = "s" x 1000;
my $r = `echo $s |more`;
But it doesn't work, my program exits directly...
It does not work in your example, because you never print $r. The output is captured in the variable $r. By using system() instead, you can see the output printed to STDOUT, but then you cannot use the output as you (probably) expected.
Just do:
print $r;
Update: I changed say to print, since "echo" already gives you a newline.
To escape shell meta characters, as mentioned in the comments, you can use quotemeta.
You should also be aware that | more has no effect when capturing output from the shell into a variable. The process is simply: echo | more | $r, and you might as well skip more.
try with the system() command :
my $s = "s" x 1000;
my $r = system("echo $s |more");
will display all your 's', and in $r you will have the result (0 in this case) of the command.