Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Start a service, wait 10 seconds, and stop the service.

by tphyahoo (Vicar)
on Jun 17, 2005 at 15:59 UTC ( #467785=perlquestion: print w/ replies, xml ) Need Help??
tphyahoo has asked for the wisdom of the Perl Monks concerning the following question:

This applies to windows with active state perl.

Let's say I have a service on my computer, it just listens on a particular port and does stuff. I want to start it in the background, and then later on (say ten seconds later) stop it. I figured out how to start it from reading the faq.

use strict; use warnings; my $result = system("C:\\Programme\\service.exe &"); print "sleeping"; sleep(3); die;

The thing is, this never dies, because the command never returns... because it is a service, it just sits there and listens and listens and listens.

But now how do I write something that starts, waits ten seconds, and stops? I guess the answer must be something along the lines of you start a separate thread that gets the process id, which returns it to the parent process, which then waits ten seconds and kills the child process... except that I have no idea how to do that.

In addition to an answer of this particular question, I would be much obliged if someone could point me towards a tutorial about the basics of systems programming. Thanks!

Comment on Start a service, wait 10 seconds, and stop the service.
Download Code
Re: Start a service, wait 10 seconds, and stop the service.
by jeffa (Chancellor) on Jun 17, 2005 at 16:01 UTC

    Blasphemy time ... why not just write a shell command instead of a Perl script for this? For example, here is what i use to restart our mod_perl enable web server for Krang:

    /usr/local/krang/bin/krang_ctl stop sleep 2 /usr/local/krang/bin/krang_ctl start
    Use the right tool for the right job. :)

    UPDATE: oh uh ... i see now that i got your order backwards ... start, wait, then stop. I'd still be tempted to solve this with a shell script rather than Perl, because you are dealing mostly with shell commands. One naive solution would be to grep for the process, but i'm sure there is a better way to capture the PID and stop it. Perhaps if you wrote some wrapper script like the apachectl script that keeps track of its PID. It writes the PID to a file and reads that file when you need to stop it. You could write the wrapper in Perl and have it accept two args: start and stop -- then use a shell script to call the Perl script.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Thanks for the quick response but.. well, is there a way to do that for tor? That's what I'm trying to do. My real script of course does stuff more complex than waiting ten seconds. :)

      UPDATE: Tor can be installed as a windows service, so I guess this question boils down to, how do I start a windows service, wait a bit, and stop it. Any ideas?

        ahhh, well next time you should mention that your script does more than sleep 10 sec...otherwise you will get an answer to what you've asked (simple and straight to the point....)
Re: Start a service, wait 10 seconds, and stop the service.
by cool_jr256 (Acolyte) on Jun 17, 2005 at 16:10 UTC
    You cane use 'open2' or 'open3' to accomplish your venture!. Here is an axample if you wanted to do bit more with the process in the future (eg: write to it, read from it, errors...)

    Example:
    $pid=open3( *wr1, *rd1, *er1, "C:\\Programme\\service.exe" ); sleep 3; close(wr1); local($/) = undef; close(rd1); close(er1); waitpid $pid, 0;
    Update:
    Of course the method mentioned in prev node would be the way to go for simplicity.....
      Very nice! Worked like a charm.
Re: Start a service, wait 10 seconds, and stop the service.
by davidrw (Prior) on Jun 17, 2005 at 16:41 UTC
    If it's a windows service (if not, you can make it into one, but that's beyond the scope of this reply), you can do a batch file or a perl script (as suggested above), but the key is to use net {start|stop} so you don't have to deal with the pids yourself (which of course is possible):
    REM batch file method: net start my_service perl -e "sleep 10" net stop my_service # perl method: system("net start my_service"); sleep 10; system("net stop my_service");
Re: Start a service, wait 10 seconds, and stop the service.
by tphyahoo (Vicar) on Jun 17, 2005 at 17:02 UTC
    Thanks, to everyone who answered. I am still not sure what I am going to do. For now I am using this code below. However, I am going to try to do as davidrw suggested, as this seems the simplest. I suppose I will have to be calling net start from within the script using backticks or system or something, but that doesn't seem like it should be a problem.
    use strict; use warnings; use IPC::Open3; #my $result = system("C:\\Programme\\Tor\\tor.exe &"); #print "sleeping"; #sleep(3); my ($WR1, $RD1, $ER1); my $tor_fhs = {}; my $pid = start_tor($tor_fhs); sleep 1; stop_tor($tor_fhs); sub start_tor { my $tor_fhs = shift; open3( $tor_fhs->{wr}, $tor_fhs->{rd}, $tor_fhs->{err}, "C:\\Progr +amme\\Tor\\tor.exe" ); print "tor started\n"; return $pid; } sub stop_tor { my $tor_fhs = shift; close($tor_fhs->{wr}); local($/) = undef; close($tor_fhs->{rd}); #close($ER1); print "tor stopped\n"; }
    UPDATE: Ack, no, maybe that wasn't such a good idea. This starts the service, but doesn't stop it, so after a bit of playing around I had a bunch of processes that I had to stop using ctrl-alt-delete. Maybe time to stop monkeying with things I don't really understand and get this working using net start and net stop.
      You're missing the
      waitpid $pid, 0;
      That's why your processes don't get stopped properly..... Update:
      Tried it without the 'waitpid' and exactly as predicted left me with "ghost" processes which I had to kill manually...

      You never kill the process, so it never dies.

      use strict; use warnings; sub start { my $pid; { # We don't need to talk to the process, # So we don't need open3. # Close communication channels. local *STDIN; local *STDOUT; local *STDERR; # Launch child process. $pid = eval { system 1, @_ }; # 1 == P_NOWAIT } die("Can't spawn-NOWAIT: $!\n") if !$pid || $pid < 0; return $pid; } sub stop { my ($pid) = @_; kill(15, $pid) and waitpid($pid, 0); } # Arguments to the program must be passed in seperate function args # For example, # # my $tor_pid = start('C:\\Programme\\service.exe', 'arg1', 'arg2'); # # If you don't, you'll get the PID of the shell that's created # to launch the program, and stop() won't work. my $tor_pid = start('C:\\Programme\\service.exe'); print "tor started\n"; sleep 3; stop($tor_pid); print "tor stopped\n";
Re: Start a service, wait 10 seconds, and stop the service.
by ikegami (Pope) on Jun 17, 2005 at 17:04 UTC

    & is specific to unix shells. The Windows shell equivalent is start:

    my $result = system("start C:\\Programme\\service.exe");

    Unforunately, start doesn't return the process id, so it's not too useful to you. It might be useful to other readers of this thread, though.

      Indeed, thanks for clarifying that. Does no process id mean I can't stop the process without dying, as I would guess is the case?
        It means you can't stop the process (with or without dying). To kill a process, you need to kill it, and kill requires the PID of the process to kill. See my other reply for working (tested) solution to your problem.
Re: Start a service, wait 10 seconds, and stop the service.
by fglock (Vicar) on Jun 18, 2005 at 05:39 UTC
Re: Start a service, wait 10 seconds, and stop the service.
by Ultra (Hermit) on Jun 18, 2005 at 10:11 UTC
    Have you looked into Win32::Service?
    I guess this is what you are looking for.
    Dodge This!
Re: Start a service, wait 10 seconds, and stop the service.
by DrHyde (Prior) on Jun 20, 2005 at 09:10 UTC
    rem this is a DOS batch file net start SERVICENAME perl -e 'sleep 10' net stop SERVICENAME

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://467785]
Approved by ghenry
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2014-07-26 15:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (178 votes), past polls