Re: Effective way in perl
by CountZero (Bishop) on Jul 16, 2009 at 06:00 UTC
|
| [reply] |
|
Hi,
My code has repetation of same lines i.e execution of same command output has been redirected to two separate log files.
Is there any way, I can use reduce the number of lines of the program in perl. Please advise.
| [reply] |
Re: Effective way in perl
by cdarke (Prior) on Jul 16, 2009 at 08:00 UTC
|
Use a subroutine for the common code, passing in the variable parts are parameters. However, these lines are not that similar. The first one does an echo and the others call $swlist as a program.
To make the code more effective in perl you can easily replace the grep program by a perl regular expression (make sure you are using Extended RE constructs in the regular expressions - grep uses Basic REs which differ slightly). You can run the $swlist program in a pipe to grab the output one line at a time, see open. | [reply] [d/l] [select] |
Re: Effective way in perl
by graff (Chancellor) on Jul 16, 2009 at 13:15 UTC
|
You seem to be running the same command two times, just to have its output stored in two distinct output files. Apart from that, I'd be worried about the risks of running shell commands that way, unless there is very hight certainty that the perl variables being used to build the command are "safe" (contain no shell metacharacters, etc).
In any case, it seems like you only need a shell to run the initial part of your pipeline, and it would be just as well for perl to do the rest:
my @command = ( $swlist, '-l', 'depot', '@', $depot_locn );
my $child_pid = open( my $shell, '-|', @command )
or die "shell command failed: $!\n";
open( my $out1, ">>", $log_std_depot ) or die "$log_std_depot: $!\n";
open( my $out2, ">>", $temp_log ) or die "$temp_log: $!\n";
print $out1 "COMMAND: @command ## FILTERS: $rel_string / $i / AR\n";
while (<$shell>) {
next unless ( /$rel_string/ and /$i/ and /AR/ );
print $out1 $_;
print $out2 $_;
}
close $out1;
close $out2;
close $shell;
Update: note that by doing the "grep" parts inside perl, you are able to make use of perl's much more powerful regex syntax -- you can do things that would not be possible with the standard command-line grep tool.
Another update: changed the code snippet to open the two output file in append mode (>> as per the OP code) rather than "truncate" mode. | [reply] [d/l] [select] |
|
Hi Graff ,
Thanks for the suggestions.
I tried running your code inside perl script.
When i execute the above code , I see only below lines in
the log file. (log_std_depot)
COMMAND: /usr/sbin/swlist -l depot @ sidedepot.fc.com ## FILTERS: 0909
/ / AR
And also $temp_log seem to be empty.
The commands are not getting executed, it only outputs the above line in the logfile.
Are we missing anything here.
| [reply] |
|
| [reply] |
|
|
Re: Effective way in perl
by rovf (Priest) on Jul 16, 2009 at 08:24 UTC
|
I guess $grep expands to the grep of your choice, and since you are redirecting the stdout, your expression is supposed to return only the stderr of the programs. Is this correct?
I don't find your code so bad (since I, personally, wouldn't care about all the grep processes you are spawning). If you wouldn't insist on separating $swlist's stdout and stderr, you could open(SWLIST,'/your/swlist|') and grep inside your Perl program. If you need to keep stdout and stderr apart, have a look at IPC::Run.
--
Ronald Fischer <ynnor@mm.st>
| [reply] [d/l] [select] |
Re: Effective way in perl
by JavaFan (Canon) on Jul 16, 2009 at 11:42 UTC
|
Assuming that $swlist constains a command having to do with HP's package system, I don't see much improvement. You'll have to spawn seperate processes anyway, and the grep utility is pretty fast.
However, it seems you are doing the same command twice, sending the resulting output to two different files; you could send the output to a (temp) file once, and then concat the output to both $log_std_depot and $temp_log.
And if you aren't using the output of the pipe chain (which wouldn't make sense, as you're sending that to the files anyway), you might prefer system over backticks. | [reply] |
Re: Effective way in perl
by QM (Parson) on Jul 16, 2009 at 16:03 UTC
|
Unix tee has always done the job for me. Do you need to append?
Update: added link.
-QM
--
Quantum Mechanics: The dreams stuff is made of
| [reply] |
|
I basically need to reduce my two-liner code to single line coz I will be handling similar situations in my remaining code. If I have repetation lines doing the same job , my code length will be too huge.
How do I use unix tee in perl script, please advise
| [reply] |
|
`$swlist -l depot @ $depot_locn | $grep $rel_string | $grep $i | $grep
+ AR >> blah`
which isn't pure perl code anyway, is it? (It's convenient to call grep 3 times, but might be more efficient to do with Perl's own grep.) Here, you're using perl just like you would use sh.
But to address your question, try:
`$swlist -l depot @ $depot_locn | $grep $rel_string | $grep $i | $grep
+ AR | tee file1 | tee file2 | tee file3 >> tee file4`
But if you need append, I don't think tee can do that.
Also take a look at Regexp Quote Like Operators and What's wrong with using backticks in a void context?
-QM
--
Quantum Mechanics: The dreams stuff is made of
| [reply] [d/l] [select] |
|