in reply to Determining if self is already running under WinNT/2000

On windows, I don't believe it is possible to trace back to the path of the script, and for a very obvious reason: Perl scripts on a win32 machine are executed via a file association: the windows registry contains entries which say that a .pl extension (for example), is to be run by Perl (located at 'c:\perl\bin\perl.exe' for example). So it's not your actual script that is being executed, it is Perl being executed, with your script name passed as an argument to perl.exe. To prove that this is true, you can remove the shebang line from scripts on a windows machine and it will still run (with the exception of CGI scripts, though I'm sure this is an Apache issue, not Perl's).

I know that *nix machines run a program under the script name rather than perl with the script name passed as an argument. I'm going to assume that this is because you are really executing the script as a program, with the shebang line pointing to the interpreter.

So, on Win32, it is not possible to get the script name (perhaps a Win32::xxxx module provides this functionality?). I would much rather avoid OS-specific modules however, and describe a cross-platform method of doing so. Use a status file. :) When your program starts up, you check for the existence of this file. If the file exists, you die with a friendly message. If it doesn't exist, you create the file. Do your work, then delete the file to allow another instance of it to start. Simple. You should probably extend the code to check the last modified date/time of the file (check out stat) and use it to see if that date is older than however long your script takes to run. Do that right, and you won't be stuck if your script is forced to exit before it deletes the file. (ie: someone ctrl+z's the script: the status file will continue to exist, though the script is no longer running. Another instance will never start until you manually delete the file). The example (low-level-code-that-needs-some-add-ons) code:

#!/usr/bin/perl -w use strict; my $stat_file = '/path/to/status.txt'; die "Another instance of this program is running!\n" if (-e $stat_file); open F, '>', $stat_file; close F; # Do all your hard work here # Nice and boring stuff here... yippee! unlink $stat_file;


If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, reply to this node or /msg me to tell me what is wrong with the post, so that I may update the node to the best of my ability. If you do not inform me as to why the post deserved a downvote, your vote does not have any significance and will be disregarded.

Replies are listed 'Best First'.
Re: Re: Determining if self is already running under WinNT/2000
by tachyon (Chancellor) on Feb 06, 2003 at 23:24 UTC

    If you are going to suggest lock files please do it right using sysopen to aviod race conitions as shown at Re: CGI Question - run external script and then update page and below. Typically you would print the PID to the lockfile:

    use Fcntl qw(O_WRONLY O_CREAT O_EXCL); my $lockfile = '/tmp/lock'; if (sysopen(FH, $lockfile, O_WRONLY | O_CREAT | O_EXCL)) { # sysopen will only work if lockfile does not exist # do stuff close FH; unlink $lockfile or die "Can't unlink lockfile $lockfile $!"; } else { die "$lockfile exists so another instance of the script is running +!"; exit; }

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Re: Determining if self is already running under WinNT/2000
by iburrell (Chaplain) on Feb 07, 2003 at 20:00 UTC
    Under ActivePerl on Windows, the $0 variable contains the name of the script. Launching through a a file association makes no difference. ActivePerl puts the script name into the $0 variable instead of the path to the Perl interpreter. The path to the interpreter is in $^X. Under Unix, Perl behaves the same way if you run the interpreter directly: 'perl script.pl'.