[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Using perl to fork a process and terminate it if over X second

Posted on 2014-04-16
15
Medium Priority
?
1,210 Views
Last Modified: 2014-04-28
Here is my problem, often that when I am using tnsping to test a TNS Alias, the command could take minutes to return if there is a network disruption.

Can I wrap the tnsping command a perl command using fork and alarm feature, so that if the child process is ubale to complete with X second, this perl command will return 1 otherwise return 0

let's say tns alias: SID_HOSTX

$ tnsping SID_HOSTX                  #could take minutes to return not ok
0
Comment
Question by:tindavid
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 3
  • +1
15 Comments
 
LVL 62

Expert Comment

by:gheist
ID: 40003920
You need to make sufe both ends are aware of own and other dns name and reverse name
0
 
LVL 9

Expert Comment

by:rfportilla
ID: 40004705
I don't know tnsping, but I don't see why you wouldn't be able to.  Do you need an example?  

Try this:

http://perldoc.perl.org/functions/alarm.html

In the eval block, I would use backticks to execute tnsping and parse the return.  You can get finer error handling that way.  

This is synchronous, however.  If you wanted to this asynchronously (with forking), it will be a little more complicated.  Let me know if this is a requirement and I can do a quick search for an example.  (or just google.  The truth is out there...)
0
 

Author Comment

by:tindavid
ID: 40005575
Yes, I needed a wrapped script to execute a Unix command will be find:

pseudo code:

tnsping is an Oracle command to test the DB connection listener.

$ tnsping abcd

where abcd is athe alias to make a ping to the port of Listener in the remote server and that port is conifgured with Oracle Listener.

I want to make sure the 'tnsping abcd' will not hanging there foe minutes and return not successful.


So, please send me the complete command syntax to do this, I presume the code will like this

Synchronize solution will be fine, I only want to know if this tnsping can return asap, so that I can make a decision .

# test tnsping connection by using perl's alarm, fork , retrun code if executed with a limited time slot (say 2 seconds)

perl -fork ......                

if  [ $? -ne 0 ]; then  ......
0
Will your db performance match your db growth?

In Percona’s white paper “Performance at Scale: Keeping Your Database on Its Toes,” we take a high-level approach to what you need to think about when planning for database scalability.

 

Author Comment

by:tindavid
ID: 40005709
Dear All,

I have managed to get an easy answer as below:

my $pid = fork;
if ($pid > 0){
    eval{
        local $SIG{ALRM} = sub {kill -9, $pid; die "TIMEOUT!"};
        alarm 10;
        waitpid($pid, 0);
        alarm 0;
    };
}
elsif ($pid == 0){
    setpgrp(0,0);
    #exec(q[sleep 2]);
    exec(q[sleep 20]);
    exit(1);
}
0
 

Author Comment

by:tindavid
ID: 40005724
hi rfportilla,

let's say the above perl code is now named as TestSleep.pl with arg1 as command

#!/usr/bin/ksh

cmd1='sleep 20'
res=`perl TestSleep.pl ${cmd1} `
if [ $res -ne 0 ]; then
   echo "$cmd1 is killed due to over the allowable time of 10 sec"
fi

however, the return code of the TestSleep.pl 'sleep 20' does not return 1.

so in my shell script I need to get the return code of excution of perl script result code

Could you help to finish this part ?

Thanks
0
 

Author Comment

by:tindavid
ID: 40005760
I need to get the status code if 9 if child process is killed and 0 if child process gets executed before alam wake up.
0
 
LVL 80

Expert Comment

by:arnold
ID: 40005843
Add to your res= assignment
; echo $?

In shell, bash $? Is the status code and will be the value assigned to res.
0
 
LVL 9

Expert Comment

by:rfportilla
ID: 40005880
I'm not completely clear on that. Are you saying that you need the status code, the child process, or both? As Arnold said, status code is easy. $?
0
 

Author Comment

by:tindavid
ID: 40013862
Yes, I need to status code of the command executed by TestSleep.pl (child process).

Togather with the script (TestSleep.pl), there should be another argument.


TestSleep.pl 5 "sleep 20" or TestSleep.pl 5 "Unix command"

Where the 5 threshold of how long the parent prcess to wait for the child process to complete.  If the threshold is over, the script should terminate the child process and return return code of child prcess.

You may ask why "sleep 20"?   So that the child prcess is always longer than the threshold of 5.

Instead of executing "sleep 20", I can execute a command of "ping xxx.xxx.xxx.x" to see if thi ping might runing over minutes to return. So if the commnad is this ping command , the return code should not be 0, correct ?

Thank you.
0
 
LVL 80

Expert Comment

by:arnold
ID: 40014034
when you run an assignment executing an external command, the status assigned will be that of ``
if you want, the output of the command, you need to echo $?
status=`run_command; echo $?`
the variable $statis will have the exit code from run_command.

You are testing the alarm functionality at this point which should be working when you only execute the perl script directly.
0
 
LVL 9

Expert Comment

by:rfportilla
ID: 40015221
You don't need to echo $? within the command.  PERL will populate the $? with the return of the last shell command run in ``.  

I still did not get a clear answer.  Why are you running this as child processes?  Is this a requirement?  I'm only asking because it makes the task more complicated and unless you have a bunch of processes to check (>20), it is much easier to handle this synchronously.
0
 
LVL 80

Expert Comment

by:arnold
ID: 40015451
Here is an explanation.
within the shell script the only thing that will be assigned to res is the output from the perl script. STDERR will not be part of the data which is what the TIMEOUT output is when the alarm is triggered.
The status of the execution of the code will be available in the $? system/environment variable. until another command is executed.

i.e. if all works right, res will have TIMEOUT when your assignment redirects 2>&1.
and $? will have the exit code
0
 

Accepted Solution

by:
tindavid earned 0 total points
ID: 40016967
Ok, I have modified my code to get an exit code.

#!/usr/bin/perl

$tme = $ARGV[0];
$cmd = $ARGV[1];

my $retval = 0;
my $pid = fork;

if ($pid > 0){
    eval{
        local $SIG{ALRM} = sub {kill -9, $pid; $retval = 99;};
        alarm $tme;
        waitpid($pid, 0);
        exit($retval);
    };
}
elsif ($pid == 0){
    setpgrp(0,0);
    exec($cmd);
    exit($retval);
}

$  perl TestCMD.pl 5 "sleep 20"
$ echo $?
99

$  perl TestCMD.pl 5 "sleep 2"
$ echo $?
0
0
 

Author Closing Comment

by:tindavid
ID: 40025568
Noone seems give the solution that I want. I found the solution myself.
0
 
LVL 9

Expert Comment

by:rfportilla
ID: 40027251
I'm not quite sure what solution you were looking for then.  I thought we gave you information relevant to solving your problem.  Maybe I'm missing something.  You wanted to to get the return for a script that you executed within PERL, right?  

Anyway, sorry we couldn't be more help.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Attention: This article will no longer be maintained. If you have any questions, please feel free to mail me. jgh@FreeBSD.org Please see http://www.freebsd.org/doc/en_US.ISO8859-1/articles/freebsd-update-server/ for the updated article. It is avail…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Learn how to navigate the file tree with the shell. Use pwd to print the current working directory: Use ls to list a directory's contents: Use cd to change to a new directory: Use wildcards instead of typing out long directory names: Use ../ to move…
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…
Suggested Courses

656 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