我如何知道我的Python脚本是否在运行?(使用Cygwin或Windows命令行)
我有一个名为 sudoserver.py
的 Python 脚本,我是在 CygWin 终端中通过以下命令启动它的:
python sudoserver.py
我打算创建一个脚本(我还不确定是用 Windows 的脚本还是 CygWin 的脚本),这个脚本需要知道 sudoserver.py
这个 Python 脚本是否正在运行。可是如果我在 CygWin 中(当 sudoserver.py
正在运行时):
$ ps -e | grep "python" -i
11020 10112 11020 7160 cons0 1000 00:09:53 /usr/bin/python2.7
而在 Windows shell 中:
C:\>tasklist | find "python" /i
python2.7.exe 4344 Console 1 13.172 KB
看起来我没有关于这个 .py
文件正在执行的信息。我只知道 Python 正在运行 某个东西。
在 CygWin 中,使用 'ps' 命令的 -l
(长格式)选项找不到我的 .py
文件。使用 tasklist
的 /v
(详细信息)选项也找不到。
那么,应该用什么合适的方式(Windows 或 CygWin 的终端都可以;如果两者都能那就更好了)来编程检查一个特定的 Python 脚本现在是否正在执行呢?
注意:这个 Python 进程可能是由其他用户启动的。甚至可能是由没有登录图形界面的用户启动的,甚至更重要的是,可能是由具有特权的 Windows 用户 "SYSTEM" 启动的。
2 个回答
因为 sudoserver.py
是你自己的脚本,所以你可以修改它,让它在启动时创建一个可以访问的文件,并在结束时删除这个文件。这样,你的 shell 脚本就可以检查这个文件是否存在,从而判断 sudoserver.py
是否在运行。
(编辑)
感谢那些评论的人,他们提到虽然文件的存在与否并不是一个可靠的指标,但文件的锁定状态却是可靠的。
我写了一个 Python 脚本 testlock.py
:
f = open ("lockfile.lck","w")
for i in range(10000000):
print (i)
f.close()
... 然后在我的 Windows 电脑上的 Cygwin 控制台窗口中运行它。同时,我在同一个目录下打开了另一个 Cygwin 控制台窗口。
首先,在我启动 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
... 然后在我用 Ctrl-C
关闭 testlock.py
之后:
Simon@Simon-PC ~/test/python
$ rm lockfile.lck
Simon@Simon-PC ~/test/python
$ ls
testlock.py
Simon@Simon-PC ~/test/python
$
因此,看起来 Windows 在 testlock.py
脚本运行时会锁定这个文件,但在用 Ctrl-C
停止它时,文件会解锁。可以用以下 Python 脚本进行等效测试:
import os
try:
os.remove ("lockfile.lck")
except:
print ("lockfile.lck in use")
... 它正确地报告:
$ python testaccess.py
lockfile.lck in use
... 当 testlock.py
正在运行时,但在用 Ctrl-C
停止 testlock.py
后,成功删除了被锁定的文件。
请注意,这种方法在 Windows 上有效,但在 Unix 上不行,因为根据 Python 文档:
在 Windows 上,尝试删除一个正在使用的文件会引发异常;而在 Unix 上,目录条目会被删除,但文件所占用的存储空间在原文件不再使用之前不会被释放。
使用一个额外的 Python 模块 FileLock 的跨平台解决方案可以在 Python 中锁定文件 中找到。
(进一步编辑)
看起来提问者并不一定想要 Python 的解决方案。另一种选择是用 bash
来实现。这里是 testlock.sh
:
#!/bin/bash
flock lockfile.lck sequence.sh
脚本 sequence.sh
只是运行一个耗时的操作:
#!/bin/bash
for i in `seq 1 1000000`;
do
echo $i
done
现在,当 testlock.sh
正在运行时,我们可以使用 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
$
前两次尝试锁定文件失败,因为 testlock.sh
仍在运行,所以文件被锁定。最后一次尝试成功了,因为 testlock.sh
已经运行结束。
这是平台的一个限制。
你可能需要使用一些底层的API来获取进程信息。你可以看看这个链接:获取Windows中另一个进程的命令行参数
你可能可以使用win32api模块来访问这些API。
(抱歉,我现在不在Windows电脑旁,所以无法试验一下)