http://www.perlmonks.org?node_id=1019308


in reply to Kill a perl script execution in windows

Try

#! perl -slw use strict; print "$0 running as $$"; my( $target ) = map { 1+ index( $_->[0] // '', $0 ) && $_->[1] != $$ ? $_->[1] : () } map[ (split ',', $_ )[1,24] ], `wmic process list full /format:csv`; if( $target ) { print "Found another running as $target; usurping it."; kill 9, $target; } sleep 1e6;

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Kill a perl script execution in windows
by rbala (Acolyte) on Feb 18, 2013 at 10:42 UTC
    Hi, Thanks for your code. In a high level , I am able to understand the script. Can you please explain how $target variable is evaluated and on what the map function is applied ? I am getting syntax error when i use this code as such . Thanks, Bala.
      Can you please explain how $target variable is evaluated and on what the map function is applied ?
      • Type the command: wmic process list full /format:csv on a windows command line to see that it produces a csv of information about the running processes.
      • Wrapping that in backticks (`...`) cause perl to run that command and capture the output.
      • It supplies that output one line at a time to the map: map[ (split ',', $_ )[1,24] ] `...`; which:
        1. splits it on the commas,
        2. extracts the second and 25th fields, which are the command line text and the process id respectively.
        3. And places those two fields from each line into its own anonymous array.
      • Those anonymous arrays are passed into the second map (appearing lexically first in the source code):
        ... = map { 1+ index( $_->[0] // '', $0 ) && $_->[1] != $$ ? $_->[1] : () } ...

        Which tests if the first value in the anonymous array ($_->[0]) contains $0 (the name&path of the current program), and if the second value in the anonymous array ($_->[1]) (the process id) is not equal to $$ (the process id of the current perl program),

        then it passes that second value (the pid) out of the map

        otherwise it returns nothing.

      • Hence, if another copy of this script is already running, $target will be assigned its pid.
      I am getting syntax error

      What is the text of the syntax error? What version of perl are you running?


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Thanks a lot! I can very well understand the logic of parsing the csv file. The error which I got was :
        Backticks found where operator expected at wmic.pl line 11, at end of +line (Missing semicolon on previous line?) syntax error at wmic.pl line 11, near "], `wmic process list full /for +mat" (Might be a runaway multi-line // string starting on line 6) Can't find string terminator "`" anywhere before EOF at wmic.pl line 1 +1.
        I am using perl version 5.18. But I made an alternative code to redirect the stdout of the wmic command to an array and got the output in a text file. The only thing I am was not able to understand was the text parsing logic using the map function. Now got it. Many thanks, once again!
        Hi, I have still one more doubt in your code . 1.What does the 1+ before indexing function signify ? 2.What is the string actually compared to $0? Thanks, Bala.