Bash

Autokey - 如果正在執行則聚焦應用程序視窗,如果沒有則啟動應用程序

  • January 22, 2022

我正在嘗試獲取這樣的 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.

執行 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]

引用自:https://unix.stackexchange.com/questions/686861