如何在 shell 脚本中关闭一个 Windows 进程,通过其参数定位它



我用来通过CygWin中包含的可执行文件运行Python程序,例如:

c:CygWinbinpython2.7.exe /usr/local/bin/FunnyProgram.py
c:CygWinbinpython2.7.exe /usr/local/bin/BoringWordProcessor.py

请注意,/usr/local...的东西是参数部分,而不是可执行程序。
我正在制作一个 Windows shell 脚本,假装关闭其中的某个人,例如"FunnyProgram.py"。但我不能做:

taskkill /im "Funny*" /f

因为操作系统似乎看到的只是:

C:>tasklist | find "python" /i
python2.7.exe                 5012 Console                    1    13.240 KB

如果我这样做,根本没有结果:

tasklist | find "Funny" /i

我也不能通过使用SysInternals PSExec找到它:

C:>pslist python -x
pslist v1.3 - Sysinternals PsList
Copyright (C) 2000-2012 Mark Russinovich
Sysinternals - www.sysinternals.com
Process and thread information for KENOBI:
Name                Pid      VM      WS    Priv Priv Pk   Faults   NonP Page
python2.7          5012  588464   13240   13416   13556     3458     11  103
 Tid Pri    Cswtch            State     User Time   Kernel Time   Elapsed Time
 580  10       316     Wait:UserReq  0:00:00.062   0:00:00.202    0:23:42.743
2760  11         4   Wait:Executive  0:00:00.000   0:00:00.000    0:23:42.741
 616   8         4     Wait:UserReq  0:00:00.000   0:00:00.000    0:23:42.597
3164  11        49     Wait:UserReq  0:00:00.000   0:00:00.000    0:23:42.460

对于 SysInternals Handle,基本相同:

C:Windowssystem32>handle -p "python"
Handle v3.51
Copyright (C) 1997-2013 Mark Russinovich
Sysinternals - www.sysinternals.com
------------------------------------------------------------------------------
python2.7.exe pid: 5012 KENOBILuis
   60: Section       BaseNamedObjectscygwin1S5-c5e39b7a9d22bafbshared.5
   64: Section       BaseNamedObjectscygwin1S5-c5e39b7a9d22bafbS-1-5-21-33151
06853-2407454319-848584108-1000.1
   70: Section       BaseNamedObjectscygwin1S5-c5e39b7a9d22bafbcygpid.5012
   C0: Section       BaseNamedObjectscygwin1S5-c5e39b7a9d22bafbc5e39b7a9d22ba
fb-cons0x240B0C.0
   CC: Section       BaseNamedObjectscygwin1S5-c5e39b7a9d22bafbcygpid.5552
  254: File  (RWD)   C:UsersLuis

如何检测PID(以便关闭它),或者至少直接关闭某些特定程序,通过其参数定位它?
(我想在 Windows shell 脚本中执行此操作,但如果需要,可以接受其他命令行实用程序

编辑:另一种方法不起作用。如果我做notepad test.txt,我可以使用PowerShell找到它:

$process = "notepad.exe"
gwmi Win32_Process -Filter "name = '$process'" | select CommandLine

我将这两行保存到"TestNotepad.ps1"中,然后我做到了:

C:>Powershell.exe -executionpolicy remotesigned -File TestNotepad.ps1
CommandLine
-----------
"C:Windowssystem32notepad.exe"
"C:Windowssystem32NOTEPAD.EXE" D:test.txt

但对于文件:

$process = "python2.7.exe"
gwmi Win32_Process -Filter "name = '$process'" | select CommandLine

我只是得到一个简单的:

C:>Powershell.exe -executionpolicy remotesigned -File TestPython.ps1
CommandLine
-----------
"C:CygWinbinpython2.7.exe"

。根本没有参数。奇怪!

Windows shell:

C:Python33python.exe c:helloworld.py

Powershell:

PS C:UsersDavid> $process = "python.exe"
PS C:UsersDavid> gwmi Win32_Process -Filter "name = '$process'" | select CommandLine
CommandLine
-----------
C:Python33python.exe  C:helloworld.py

从Windows Shell调用Python在Cygwin\bin:

c:cygwinbinpython3.2m.exe c:helloworld.py

Powershell:

PS C:UsersDavid> $process = "python3.2m.exe"
PS C:UsersDavid> gwmi Win32_Process -Filter "name = '$process'" | select CommandLine
CommandLine
-----------
C:cygwinbinpython3.2m.exe  C:helloworld.py

这个问题似乎来自官方CygWin存储库中包含的Python解释器(截至今天,v2.7.3)。令人高兴的是,解决方案本身似乎在自己的CygWin pgrep命令上。

假设这个命令行运行 Python 进程:

c:CygWinbinpython2.7.exe /usr/local/bin/FunnyProgram.py
-

-> 要查找进程,我们可以将pgrep-f选项一起使用(搜索完整路径):

$ pgrep -f -l FunnyProgram.py
2640 /usr/bin/python2.7 /usr/local/bin/FunnyProgram.py
-

-> 直接终止进程:

$ kill $(pgrep -f FunnyProgram.py)

我不知道为什么pstasklist或任何其他命令无法执行pgrep所做的事情。

根据@DeveloperGuo的说法,这个问题可以在v3及更高版本中解决。

可悲的是,Python v2 和 v3 脚本不兼容,所以我希望这个线程可以帮助任何来到这里寻找知识和愿望的人:-)。