Autokey - 如果正在运行则聚焦应用程序窗口,如果没有则启动应用程序

Autokey - 如果正在运行则聚焦应用程序窗口,如果没有则启动应用程序

pcmanfm我正在尝试获取这样的processID :

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如果它当前没有运行,这确实会扰乱我的启动能力。我的脚本认为它正在运行,但实际上它没有运行。

为什么会发生这种情况?

我实际上遇到了这个问题自动键我尝试根据此编写的脚本视频我看了。这是我当前的脚本:

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)

答案1

建议的解决方案:

-f从命令中删除该选项pgrep


解释:

您可能会获取为运行命令而执行的 shell 的进程 ID。将为每个system.exec_command.

运行egsh -c 'pgrep -af nonexistent'并检查输出。你可能会得到类似的东西

11300 sh -c pgrep -af nonexistent

使用现有命令,我还得到了 shell 的一行

sh -c 'pgrep -af sshd'
695 /usr/sbin/sshd -D
11207 sshd: pi [priv]
11224 sshd: pi@pts/0
11331 sshd: [accepted]
11343 sh -c pgrep -af sshd

根据 PID 值,您的head命令可能会提取您正在查找的进程的 PID 或 shell 进程的 PID。

使用选项,-f您可以明确指示pgrep搜索整个命令行,而不仅仅是进程名称。这样它将在 shell 的命令行参数中找到该字符串。

没有的话-f你将无法获得 shell 进程。

$ sh -c 'pgrep -a sshd'
695 /usr/sbin/sshd -D
11207 sshd: pi [priv]
11224 sshd: pi@pts/0
11364 sshd: [accepted]

答案2

以下是我对程序窗口正在运行时聚焦或未运行时启动程序的看法。我用了火狐浏览器在这个例子中,但我希望它能以同样的方式为你工作pcmanfm如果您进行了适当的编辑以删除火狐浏览器从示例代码中并将其替换为等效的PCManFM信息。

请注意,我使用了子进程.Popen函数,因为它允许您执行其他代码和/或与进程交互子进程.通信进程运行时起作用。如果不需要,您可以使用子进程.运行函数代替。

output = system.exec_command("wmctrl -l", getOutput=True)
if "Firefox" in output:
    window.activate("Firefox",switchDesktop=True)
else:
    subprocess.Popen(["firefox"])

相关内容