Perl script to kill the process ID of a command after a certain period

All,

I am trying to build a script in perl that will alllow me to pass the IP address to a ping command and redirect the output to a file and then kill that process after a certain period of time.

let's say, I call my script ping.pl, I would like to be able to run it like this for example : ./ping.pl 127.0.0.1 60 (where 127.0.0.1 will be the ip address I want to run the ping command on and 60 will be the period is seconds I would like the ping command to run and kill process ID for this ping command after this period).

I started out like this, but it looks like when I enter the command ./ping.pl 127.0.0.1 60. Nothing never happens. When I type in the IP, hit enter and type 60, hit enter. It starts working. It creates the file, but it never stops running. The process has never been killed. Any help will be appreciated.

I would like to be able to run the script on one line command with the arguments like ./ping.pl 127.0.0.1 60 ( it could be any IP and any time).

Thanks,

#!/usr/bin/perl
$i = <STDIN>;
$j = <STDIN>;
system("ping $i > ping.pl.txt");
system("sleep $j");
system("kill -9 `ps aux |grep ping|awk '{ print $2 }' ");

i see you use system tools within your Perl script. If that's the case, ditch this ugly method, and do everything with a shell script. Use $1, $2 as your arguments.

Ugh... That looks as out of place as Pavarotti in a Bon Jovi concert. Please do yourself a favor and use a shell script.

tyler_durden

I'm not if the perl system commands are the exact same as shell commands, butif they are, the ping command will just keep pinging forever, so the script is effectively stuck on the ping line and never gets to the sleep or kill lines.

Use "ping -c " to ping a certain number of times, e.g. "ping -c 2 google.com" will ping twice, or use "&" to put the ping line in the background.

Try this shell script:

#! /bin/sh
ping $1 >> ping.txt &
sleep $2
kill -9 `ps aux | grep ping | awk '{ print $2 }'`

The proper way is to record the pid of the child processes that need to be monitored and use that in the kill operation.

#!/bin/sh
ping $1 > ping.sh.txt &
pid=$!
sleep $2
kill $pid

Also, liberal use of kill -9 is not good practice and this should be avoided. A simple killl should suffice, perhaps with an additional check that may lead to further action.

Perhaps we should call it: UUoK-9 :wink:

Also - in situations where there still is a need to get the pid off the process list - note that with

kill $(ps aux | grep ping | awk '{ print $2 }' )

the grep process gets selected and killed too..
You can avoid that by using

kill $(ps | grep ping | grep -v grep | awk '{print $1}' )

or more efficiently (and since this is a child process there is no need for the arguments to ps)

kill $(ps | grep pin[g] | awk '{print $1}')

or more efficiently

kill $(ps | awk '/ping/{print $1}')

or if you do not need portability and you system supports it:

kill $(pgrep ping)

Or if you are feeling lucky:

pkill ping

Of course with some pings there is no need for kill since you can just specify how long it should be active, so you could e.g. just use

#!/bin/sh
ping $1 -w $2 > ping.sh.txt &

Thanks all for the feedback.

Scrutinizer,

Your post really scrutinize the problems and give me all kind of possible solutions. It's really appreciated. I cannot ask for more.

The only thing is that it looks like there is no simple way we can have perl do the same thing. is that a fair statement?

Thanks Pouchie1. No I think it can be done using Perl. You could probably use Net::Ping (I haven't used it myself). What is being said is that if you are going to use system tools to accomplish your goal then effectively you are using almost only external commands and you might as well use a shell script instead.

Thanks so much.