• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3081
  • Last Modified:

backtick variable substitution

Hi all,

Hopefully someone can help me out with this one.

I have a perl script that runs rsh commands to monitor a remote server.  To minimize time and bandwidth I need to maximize the processing that is done on the remote server and minimize the number of rsh commands done.

My question is, how can I place a while loop within a system call so that the loop variable is substituted correctly?  Here is an example:


$THE_ERRORS =
`rsh remote_box "cat -n app_error.log | grep 'error' |
cut -f 1 | while read x; do head -\$x app_error.log | tail -2; done"`;

Basically, I'm trying to get the error message line and the line before it returned into $THE_ERRORS.  The problem is that $x is not being interpreted correctly by the head command.

For simplicity, we can take the whole rsh out of the picture and use this as an example:

$THE_ERRORS =
`cat -n app_error.log | grep 'error' |
cut -f 1 | while read x; do head -\$x app_error.log | tail -2; done`;


Thanks for any suggestions.
0
hmdan
Asked:
hmdan
1 Solution
 
ozoCommented:
$THE_ERRORS =
`cat -n app_error.log | grep 'error' | cut -f 1 | while read x; do head -\$x app_error.log | tail -2; done`;

seems to work for me.
what error are you getting?
0
 
hmdanAuthor Commented:
$x seems to be null or blank so the head command fails.

It works at a ksh prompt:

harold$ cat -n app_system.log.7 | grep 'period' | cut -f 1 | while read x; do head -$x app_system.log.7 | tail -2

15-APR-2004 10:49:03  PI-I-PI_Log_Report_Period
  Report period 01/01 00:00 - 04/15 23:59. From time 1072933200 to 1082087940.
15-APR-2004 10:49:54  PI-I-PI_Log_Report_Period
  Report period 01/01 00:00 - 04/15 23:59. From time 1072933200 to 1082087940.
15-APR-2004 12:54:30  PI-I-PI_Log_Report_Period
  Report period 01/01 00:00 - 04/15 23:59. From time 1072933200 to 1082087940.
15-APR-2004 12:54:59  PI-I-PI_Log_Report_Period
  Report period 01/01 00:00 - 04/15 23:59. From time 1072933200 to 1082087940.
15-APR-2004 12:55:32  PI-I-PI_Log_Report_Period
  Report period 01/01 00:00 - 04/15 23:59. From time 1072933200 to 1082087940.


When run from my perl script I get this.

harold$ /home/harold/bin/search.pl
Usage: head [-Count | -n Number | -c Number] [File...]
Usage: head [-Count | -n Number | -c Number] [File...]
Usage: head [-Count | -n Number | -c Number] [File...]
Usage: head [-Count | -n Number | -c Number] [File...]
Usage: head [-Count | -n Number | -c Number] [File...]

Adding a "echo $x" line only displays blank lines.  Hmmm...  I wonder why yours works and mine doesn't.  
0
 
TintinCommented:
Do you actually have any Perl in your Perl script?

It's a serious question.  Perhaps it would be much better written as a shell script.  If you find you are using a whole bunch of external commands in your Perl script, you're either not aware of the Perl functions to perform the tasks, or it should be written as a shell script.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

 
stefan73Commented:
Hi hmdan,
> cat -n app_error.log | grep 'error' | cut -f 1 | while read x; do head -\$x app_error.log | tail -2; done

Put your while loop in ():

cat -n app_error.log | grep 'error' | cut -f 1 | ( while read x; do head -\$x app_error.log | tail -2; done )

Cheers,
Stefan
0
 
stefan73Commented:
Tintin,
> Do you actually have any Perl in your Perl script?

Good one. As one of Perl's strenghts is that the number of created external processes is reduced, you're throwing away your best speed advantage.

Use Perl to parse your error file:

open (ERRLOG,"<app_system.log") or die "Can't open app_system.log";
while($line=<ERRLOG>){
    if($line =~ /period/){
        print $line;
        $printnext=1;
    } elsif ($printnext){
        print $line;
        $printnext=0;
    }
}
close ERRLOG;
   

Stefan
0
 
hmdanAuthor Commented:
>  Do you actually have any Perl in your Perl script?

Yes, I do.  This is just one portion of a much larger monitoring script.

> you're either not aware of the Perl functions to perform the tasks, or it should be written as a shell script.

You are correct:  I am not aware of an rsh function for perl, but the existing perl script is written and functioning fine.  It sure would be a hassle to re-write the whole thing as a shell script just to get this one command to work.  The only external commands in the script are rsh commands.

> Put your while loop in ():
Thanks for the suggestion, but it did not work.

> Use Perl to parse your error file:
The error file is on a remote server - that's why I need the rsh command.  



0
 
stefan73Commented:
hmdan,
> The error file is on a remote server - that's why I need the rsh command
Aha. This changes things.

Check that you properly escape everything which is to run on the remote side. Example:

rsh host cat -n app_error.log | grep 'error'
is a lot different from
rsh host cat -n app_error.log "|" grep 'error'

In the first example, the entire cat output is transferred from the remote machine to you local machine and filtered there.
In the second example, grep filtering is done one the remote machine and only the result is transferred.
(The | ends the rsh command in the first line, but is interpreted as a normal argument in the 2nd.)
The same applies to ";".


Everything which should be quoted must be quoted twice, as you have both the local sh and the remote sh commands interpreting it.

So your command should be something like

rsh host cat -n app_error.log "|" grep error "|" cut -f 1 "|" while read x";" do head '-\$x' app_error.log "|" tail -2";" done


Stefan
0
 
hmdanAuthor Commented:
> rsh host cat -n app_error.log "|" grep error "|" cut -f 1 "|" while read x";" do head '-\$x' app_error.log "|" tail -2";" done

THANK YOU!

Kick ass... it worked.  You made my Friday, Stefan.  

Have a great weekend.

-harold
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now