Solved

backtick variable substitution

Posted on 2004-04-22
8
3,042 Views
Last Modified: 2012-06-27
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
Comment
Question by:hmdan
8 Comments
 
LVL 84

Expert Comment

by:ozo
Comment Utility
$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
 

Author Comment

by:hmdan
Comment Utility
$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
 
LVL 48

Expert Comment

by:Tintin
Comment Utility
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
 
LVL 12

Expert Comment

by:stefan73
Comment Utility
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 12

Expert Comment

by:stefan73
Comment Utility
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
 

Author Comment

by:hmdan
Comment Utility
>  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
 
LVL 12

Accepted Solution

by:
stefan73 earned 125 total points
Comment Utility
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
 

Author Comment

by:hmdan
Comment Utility
> 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

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Perl count the hash for print 4 155
Replace  text in a file 2 83
PERL - Find newest folder 12 100
File Find regex problem 4 57
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now