我正在尝试获取这样的 processID pcmanfm
:
pgrep -f "pcmanfm"
当pcmanfm
没有运行时,上面的命令什么都不返回(正如我所料)。
但是,当我从 python 运行命令时,即使pcmanfm
未运行,它也会返回一个进程 ID:
processID = os.system('pgrep -f "pcmanfm"')
此外,如果您在 python3 提示符下多次运行上述命令,则每次都会返回不同的 processID。一直以来,pcmanfm
在这些命令之前已经关闭。
>>> processID = os.system('pgrep -f "pcmanfm"')
17412
>>> processID = os.system('pgrep -f "pcmanfm"')
17414
>>> processID = os.system('pgrep -f "pcmanfm"')
17416
pcmanfm
如果它当前没有运行,这真的会破坏我的启动能力。我的脚本认为它不是在运行时。
为什么会这样?
实际上,我在尝试根据我观看的视频编写的Autokey脚本中遇到了这个问题。这是我当前的脚本:
processID = system.exec_command('pgrep -f "pcmanfm" | head -1',True)
dialog.info_dialog("info",processID)
if (processID):
cmd = "wmctrl -lp | grep " + processID + " | awk '{print $1}'"
windowID = system.exec_command(cmd,True)
# dialog.info_dialog("info",windowID)
cmd = "wmctrl -iR " + windowID
#dialog.info_dialog("info",cmd)
system.exec_command(cmd,False)
else:
#os.system("pcmanfm /home/user/Downloads")
cmd = "/usr/bin/pcmanfm /home/user/Downloads"
system.exec_command(cmd,False)
问题是,即使pcmanfm
没有运行,我也会不断获取 processID。如果脚本正在运行,则该脚本会正确聚焦pcmanfm
,但如果不是,则不会启动它。
更新:我终于通过取出-f
并替换它-nx
(来自@they 的建议)来让这个脚本工作。此外,我添加了一些异常处理来忽略由预期的空输出引起的自动键异常。此外,我将它转换为(更灵活的)功能,以便它可以服务于更广泛的命令/应用程序:
import re
def focusOrLaunch(launchCommand):
appName = re.findall('[^\s/]+(?=\s|$)',launchCommand)[0]
processID = None
try:
processID = system.exec_command('pgrep -nx "' + appName + '"',True)
except Exception as e:
#dialog.info_dialog("ERROR",str(e))
pass
#dialog.info_dialog("info",processID)
if (processID):
cmd = "wmctrl -lp | grep " + processID + " | awk '{print $1}'"
windowID = system.exec_command(cmd,True)
# dialog.info_dialog("info",windowID)
cmd = "wmctrl -iR " + windowID
#dialog.info_dialog("info",cmd)
system.exec_command(cmd,False)
else:
system.exec_command(launchCommand,False)
cmd = "/usr/bin/pcmanfm ~/Downloads"
focusOrLaunch(cmd)
建议的解决方案:
从您的命令中删除该
-f
选项。pgrep
解释:
您可能会获得为运行您的命令而执行的 shell 的进程 ID。将为每个
system.exec_command
.运行 eg
sh -c 'pgrep -af nonexistent'
并检查输出。你可能会得到类似的东西使用现有命令,我还得到了 shell 的一行
根据 PID 值,您的
head
命令可能会提取您正在查找的进程的 PID 或 shell 进程的 PID。使用选项
-f
,您明确告诉pgrep
搜索整个命令行而不是仅搜索进程名称。这样,它将在 shell 的命令行参数中找到字符串。没有
-f
你就不会得到shell进程。这是我的看法,如果它正在运行或启动程序,如果它不是,则聚焦程序的窗口。我在示例中使用了Firefox ,但如果您进行适当的编辑以从示例代码中删除Firefox并将其替换为等效的PCManFM信息,我希望它对您的pcmanfm的工作方式相同。
请注意,我使用了subprocess.Popen函数,因为它允许您在进程运行时执行其他代码和/或使用subprocess.communicate函数与进程交互。如果不需要,您可以改用subprocess.run函数。