Unix commands and perl

A

AS

Hi,

I tried to run a set of Unix commands (separated by |) using the
'system' command from a perl script, but only a single command works.
What is a good way to do this?

I need to take the output of one command put it into the next one use
that ooutput in a third command. e.g.,
system ('id | awk '{print $2}' | cut -d\( -f2 | cut -d\) -f1');

This command in itself gives me the current user's set primary group
in Unix (Solaris)
 
S

Sherm Pendley

AS said:
I need to take the output of one command put it into the next one use
that ooutput in a third command. e.g.,
system ('id | awk '{print $2}' | cut -d\( -f2 | cut -d\) -f1');

Is that your real code? If so, you have the quoting mixed up - that
doesn't even parse.

Fix the quoting by escaping the inner set of single quotes like this:
'... | awk \'{print $2}\' | ...'

sherm--
 
X

xhoster

Hi,

I tried to run a set of Unix commands (separated by |) using the
'system' command from a perl script, but only a single command works.
What is a good way to do this?

I need to take the output of one command put it into the next one use
that ooutput in a third command. e.g.,
system ('id | awk '{print $2}' | cut -d\( -f2 | cut -d\) -f1');

That doesn't compile. It gives up when you juxtapose the string
'id | awk '
next to the apparent hash reference
{print $2}
with out an operator.

And system doesn't capture the output of whatever it runs, anyway.
You want backticks or qx.
This command in itself gives me the current user's set primary group
in Unix (Solaris)

Since you are using Perl anyway, why not just use `id` and then parse the
result in Perl?

Xho
 
C

Christopher Nehren

Since you are using Perl anyway, why not just use `id` and then parse the
result in Perl?

Or use one or a couple of the get* functions, which has the benefit of
not returning tainted data.
 
M

Michele Dondi

I need to take the output of one command put it into the next one use
that ooutput in a third command. e.g.,
system ('id | awk '{print $2}' | cut -d\( -f2 | cut -d\) -f1');

Incidentally it's very very poor programming to use clumsy constructs
calling external programs to do something that perl can do more
reliably, clearly and fast in the first place.

In other words, no need and (no gain!) to use perl like shell
scripting: use shell scripting if you really want that...


Michele
 
A

AS

Thanks Xho, Villy, Christopher for your constructive suggestions.

Sorry, everyone got distracted by my EXAMPLE. That is just one of my
set of commands that I wanted to use. It works fine from the Unix
command line and I tried to use it within Perl to try to understand
how Perl works. I wanted to understand using something that I
understood already. I will be probably using this in several different
ways until I understand fully how to use all the various parts of
Perl.

My point is -- what do I need to do to run multiple commands taking
the output from one command into another? I am comparatively new to
Perl and am just getting back into programming. Michele, I would
appreciate it if you would add "how to do it" rather than just telling
me it can be done in Perl better. In this example if someone explains
to me what to do to make it work, I will be very thankful.

BTW, you guessed right, I did not know about q// quoting till after I
saw your response and searched for it. Thanks for a constructive
suggestion.
 
J

James Willmore

Hi,

I tried to run a set of Unix commands (separated by |) using the
'system' command from a perl script, but only a single command works.
What is a good way to do this?

I need to take the output of one command put it into the next one use
that ooutput in a third command. e.g.,
system ('id | awk '{print $2}' | cut -d\( -f2 | cut -d\) -f1');

This command in itself gives me the current user's set primary group
in Unix (Solaris)

To get the same infomation in a Perl one-liner (note: in Linux, I have my
own group for my UID; it's not really a wise thing in a production
environment):

[jim@localhost jim]$ perl -e 'print [getgrgid($<)]->[0],"\n";'
jim
[jim@localhost jim]$

Type `perldoc User::pwent` or `perldoc User::grent` or `perldoc perlvar`
at the command line to get documentation explaining what I did.

HTH

Jim
 
X

xhoster

Thanks Xho, Villy, Christopher for your constructive suggestions.

Sorry, everyone got distracted by my EXAMPLE. That is just one of my
set of commands that I wanted to use. It works fine from the Unix
command line and I tried to use it within Perl to try to understand
how Perl works. I wanted to understand using something that I
understood already.

Ah, well then. Calling system (or using backticks) can be particularly
troublesome when you need to consider shell escaping and shell
interpolation and shell quoting and Perl escaping and Perl interpolation
and Perl quoting all together in one messy mess. My second rule of thumb
is when in doubt, temporarily change the "system" to a "print", and make
sure that what is getting printed matches what you think the shell is
supposed to be seeing. (Does not apply to the multi-argument form of
"system", or course)


Xho
 
J

Joe Smith

AS said:
My point is -- what do I need to do to run multiple commands taking
the output from one command into another?

The example you gave works as long as you use the correct quoting
characters, and remember to put a backslash in front of the dollar
signs otherwise perl will do variable substitution.

my $cmd = "prog1 | prog2 '\$1' | prog3";
print "Command = $cmd\n";
(system $cmd) == 0 or die 'Command failed';

-Joe
 
M

Michele Dondi

[jim@localhost jim]$ perl -e 'print [getgrgid($<)]->[0],"\n";'

Not that I find it disturbing or incorrect, but what is this business
of referencing and dereferencing?

perl -le 'print +(getgrgid $<)[0]'


Michele
 
M

Michele Dondi

My point is -- what do I need to do to run multiple commands taking
the output from one command into another? I am comparatively new to
Perl and am just getting back into programming. Michele, I would

You don't need anything particular. I think you just want to read

perldoc -q 'output of a command'
appreciate it if you would add "how to do it" rather than just telling
me it can be done in Perl better. In this example if someone explains
to me what to do to make it work, I will be very thankful.

Well, any introductory reading on perl, including what you can find in
the docs would help you to find "how to do it". However, let me see...
in your post you had:

: system ('id | awk '{print $2}' | cut -d\( -f2 | cut -d\) -f1');

then incorrect quoting apart and notwithstanding the fact that another
user already suggested a "pure perl" solution, let's suppose that we
want to parse the output of id anyway: one of the many possible ways
could be (untested)

print do {
local $_=qx/id/;
(split)[0] =~ /\((\w+)\)/g;
}

or

{
local $_=qx/id/;
print +(split)[0] =~ /\((\w+)\)/g;
}

or...


HTH,
Michele
 
J

James Willmore

[jim@localhost jim]$ perl -e 'print [getgrgid($<)]->[0],"\n";'

Not that I find it disturbing or incorrect, but what is this business
of referencing and dereferencing?

perl -le 'print +(getgrgid $<)[0]'

That's better. I always have to work a little bit harder than I need to :)

Jim
 
A

Anno Siegel

James Willmore said:
[jim@localhost jim]$ perl -e 'print [getgrgid($<)]->[0],"\n";'

Not that I find it disturbing or incorrect, but what is this business
of referencing and dereferencing?

perl -le 'print +(getgrgid $<)[0]'

That's better. I always have to work a little bit harder than I need to :)

That's what getgrgid() returns in scalar context anyway:

perl -le 'print scalar getgrgid $<'

is a little longer, but conceptually simpler.

Anno
 
B

Ben Morrow

Quoth (e-mail address removed)-berlin.de (Anno Siegel):
James Willmore said:
On Mon, 29 Nov 2004 12:37:19 -0500, James Willmore

[jim@localhost jim]$ perl -e 'print [getgrgid($<)]->[0],"\n";'

Not that I find it disturbing or incorrect, but what is this business
of referencing and dereferencing?

perl -le 'print +(getgrgid $<)[0]'

That's better. I always have to work a little bit harder than I need to :)

That's what getgrgid() returns in scalar context anyway:

perl -le 'print scalar getgrgid $<'

is a little longer, but conceptually simpler.

Or, even clearer IMHO

use User::grent;

print getgr($<)->name;

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top