1

I have a python script named sudoserver.py that I start in a CygWin shell by doing:

python sudoserver.py

I am planning to create a shell script (I don't know yet if I will use Windows shell script or a CygWin script) that needs to know if this sudoserver.py python script is running. But if I do in CygWin (while sudoserver.py is running):

$ ps -e | grep "python" -i
    11020   10112   11020       7160  cons0   1000 00:09:53 /usr/bin/python2.7

and in Windows shell:

C:\>tasklist | find "python" /i
python2.7.exe                 4344 Console                    1    13.172 KB

So it seems I have no info about the .py file being executed. All I know is that python is running something.
The -l (long) option for 'ps' on CygWin does not find my .py file. Nor does it the /v (verbose) switch at tasklist.
What should be the appropriate shell (Windows or CygWin shell would enough; both if possible would be fine) way to programmatically find if an specific python script is executing right now?

NOTE: The python process could be started by another user. Even from a user not logged in a GUI shell, and, even more, the "SYSTEM" (privileged) Windows user.

Simon
  • 10,679
  • 1
  • 30
  • 44
Sopalajo de Arrierez
  • 3,543
  • 4
  • 34
  • 52

2 Answers2

2

It is a limitation of the platform.

You probably need to use some low level API to retrieve the process info. You can take a look at this one: Getting the command line arguments of another process in Windows

You can probably use win32api module to access these APIs.

(Sorry, away from a Windows PC so I can't try it out)

Community
  • 1
  • 1
Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
  • 1
    This answers the question that I also initially thought the OP was asking. In fact, however, it appears to me that the question is: "How (whether in Cygwin or Windows shell) can I find out if a specific Python script is running?" – Simon Mar 21 '14 at 23:40
  • @Simon You are right. I have proposed another solution – Anthony Kong Mar 22 '14 at 00:18
  • 1
    +1: Better than my answer, which has the flaws that commentators have pointed out when `sudoserver.py` is terminated in improperly. – Simon Mar 22 '14 at 00:27
  • Well, thanks you, @AnthonyKong. I will probably have to add C programming to my script, so it seems there is no way (till we now know) to do it. – Sopalajo de Arrierez Mar 22 '14 at 02:11
2

Since sudoserver.py is your script, you could modify it to create a file in an accessible location when it starts and to delete the file when it finishes. Your shell script can then check for the existence of that file to find out if sudoserver.py is running.

(EDIT)

Thanks to the commenters who suggested that while the presence or absence of the file is an unreliable indicator, a file's lock status is not.

I wrote the following Python script testlock.py:

f = open ("lockfile.lck","w")
for i in range(10000000):
    print (i)
f.close()

... and ran it in a Cygwin console window on my Windows PC. At the same time, I had another Cygwin console window open in the same directory.

First, after I started testlock.py:

Simon@Simon-PC ~/test/python
$ ls
lockfile.lck  testlock.py

Simon@Simon-PC ~/test/python
$ rm lockfile.lck
rm: cannot remove `lockfile.lck': Device or resource busy

... then after I had shut down testlock.py by using Ctrl-C:

Simon@Simon-PC ~/test/python
$ rm lockfile.lck

Simon@Simon-PC ~/test/python
$ ls
testlock.py

Simon@Simon-PC ~/test/python
$

Thus, it appears that Windows is locking the file while the testlock.py script is running but it is unlocked when it is stopped with Ctrl-C. The equivalent test can be carried out in Python with the following script:

import os
try:
    os.remove ("lockfile.lck")
except:
    print ("lockfile.lck in use")

... which correctly reports:

$ python testaccess.py
lockfile.lck in use

... when testlock.py is running but successfully removes the locked file when testlock.py has been stopped with a Ctrl-C.

Note that this approach works in Windows but it won't work in Unix because, according to the Python documentation:

On Windows, attempting to remove a file that is in use causes an exception to be raised; on Unix, the directory entry is removed but the storage allocated to the file is not made available until the original file is no longer in use.

A platform-independent solution using an additional Python module FileLock is described in Locking a file in Python.

(FURTHER EDIT)

It appears that the OP didn't necessarily want a solution in Python. An alternative would be to do this in bash. Here is testlock.sh:

#!/bin/bash
flock lockfile.lck sequence.sh

The script sequence.sh just runs a time-consuming operation:

#!/bin/bash
for i in `seq 1 1000000`;
do
    echo $i
done

Now, while testlock.sh is running, we can test the lock status using another variant on flock:

$ flock -n lockfile.lck echo "Lock acquired" || echo "Could not acquire lock"
Could not acquire lock

$ flock -n lockfile.lck echo "Lock acquired" || echo "Could not acquire lock"
Could not acquire lock

$ flock -n lockfile.lck echo "Lock acquired" || echo "Could not acquire lock"
Lock acquired

$

The first two attempts to lock the file failed because testlock.sh was still running and so the file was locked. The last attempt succeeded because testlock.sh had finished running.

Community
  • 1
  • 1
Simon
  • 10,679
  • 1
  • 30
  • 44
  • 2
    Unless the script dies unexpectedly. Maybe he could use a lock file, as locks are released no matter how the script is terminated. Maybe some adaption of this: http://stackoverflow.com/questions/6146523/running-python-script-with-cron-only-if-not-running – Hyperboreus Mar 22 '14 at 00:01
  • That is if file locking works on Windows as one would expect. No idea about Windows. – Hyperboreus Mar 22 '14 at 00:02
  • Yeah, I thought about the creation of some file. But it didn't seem a very elegant method, mostly due to that problem about program's hanging. Even more: the `sudoserver.py` script is intended to be stoped via **Ctrl+C**, so deletion of the lock file could be an issue. – Sopalajo de Arrierez Mar 22 '14 at 00:09
  • 1
    Planning to stop something by ^C is not a good thing, because unless you actuall handle the interrupt, i.e. create exit methods, you will hardly ever get a clean exit. As the server probably listens on some port you could just check if that port is currently in use to determine if the server is running. I'd go for the lockfile, though. – Cu3PO42 Mar 22 '14 at 00:13
  • 1
    @SopalajodeArrierez The creation of a file must not be unelegant. Other OS (those whose zen is "everything is a file") use pid-files and lock-files as a standard mechanism. You just have to check how fcntl.LOCK_EX and fcntl.LOCK_NB work on your OS and FS. – Hyperboreus Mar 22 '14 at 01:48
  • Yes, lockfile is a possibility, even with all their issues. Thanks, @Hyperboreus. – Sopalajo de Arrierez Mar 22 '14 at 02:12
  • You are right, @Cu3PO42, the server listen at port 7070TCP. This could be a possibility. Thanks. – Sopalajo de Arrierez Mar 22 '14 at 02:12
  • 1
    @SopalajodeArrierez You said "so deletion of the lock file could be an issue.". This is not an issue. No need to actually delete the file. To check whether the process is running, dont see if the file exists, but see if someone holds a lock over this file. This is how lock files work. Otherwise you have the same unreliable mechanism as proposed by Simon. And locks are released no matter how the process terminated: gracefully, ^C, SIGTERM, kill -9, computer on flames. – Hyperboreus Mar 22 '14 at 14:50
  • @SopalajodeArrierez: does [`atexit` callbacks](http://docs.python.org/3/library/atexit.html) run on `Ctrl+C` on Windows (they run on Linux on SIGINT (caused by `Ctrl+C`) because it is transformed into KeyboardInterrupt exception in Python). If they do then you could put your clean up code there – jfs Mar 22 '14 at 17:05
  • @Simon, I have checked your `testlock.py` from a **Bash** Cygwin shell and the file is deleted during the script execution (*counting numbers on screen*) with no problem. Even when running `testlock.py` from UAC elevation **Bash** CygWin console, and deleting from normal **Bash** CygWin console. Am I missing something? – Sopalajo de Arrierez Mar 23 '14 at 19:28
  • @SopalajodeArrierez: Your result (where `rm` or `os.remove()` deletes the lock file while `testlock.py` is running, in Windows) differs from my result and would appear to differ from the Python documentation for Windows that I referenced. I'm running Windows 7 and close around a year-old version of Cygwin and `bash` in the Cygwin console. I can't immediately see a reason for the difference, however. You might want to try the `FileLock` module that I referenced instead. – Simon Mar 23 '14 at 19:35
  • Sorry, @Simon, but I am not experienced in **Python programming**, and I don't know very well how to deal with that `FileLock` python module (I have installed it, but it doesn't seem to add any command to CygWin, then it must be a Python library, I suppose). So my initial wish of programming the script in **Windows or Linux (CygWin) shell**. My Windows 7 SP1 (updated) has latest CygWin installed. – Sopalajo de Arrierez Mar 23 '14 at 20:09
  • @Simon, to make your `testlock.py` I needed to add `#!/usr/bin/env python` on the first line of it. Maybe I am missing some other line? I know nothing about python scripts (my initial question was about **Windows or CygWin shell scripting**; I think I will open another thread asking exactly for it, as long as the subject differs a bit). – Sopalajo de Arrierez Mar 23 '14 at 20:27
  • @SopalajodeArrierez: I've just tried my script on a different computer, which is running Windows 7 Enterprise SP1 and got the same result as I had before. I provided the solution in Python because the question said that a Python script was being used but I'll edit my answer to include an equivalent solution in `bash` as well. – Simon Mar 23 '14 at 20:31
  • I have finally tested all your proposals, @Simon , but none of them does work. At least in CygWin. The `lockfile.lck` can allways be deleted during execution of the locking script (whether bash shell or python scrip; I have even edited my original .py script as you suggest, with no luck). The `flock` program allways returns `Lock acquired` message. Tested too on Windows XP SP3, with same results. – Sopalajo de Arrierez Apr 02 '14 at 22:56
  • @Simon, the `flock` method works on Kali Linux (not CygWin), at least the message is now `Could not acquire lock`. For deletion: I can allways delete the lock file using `rm`. – Sopalajo de Arrierez Apr 02 '14 at 23:03
  • @Simon, I have tested with a `lockfile.lck` in `/home/user/temp` and in `/tmp`. Results are the same: it can allways be deleted and I get 'Lock Acquired`, whether I use shell scripting or Python. What is going on with file locking on CygWin? – Sopalajo de Arrierez Apr 02 '14 at 23:15
  • @Simon, I don't understand why, but now some of my tests seem to be working for the `flock` method. I will keep researching and report here as long as I understand anything. This seems sorcery, for now, I swear. (Note: the lock file can allways be deleted, however) – Sopalajo de Arrierez Apr 02 '14 at 23:43