Autokey - 실행 중인 경우 응용 프로그램 창에 초점을 맞추고, 그렇지 않은 경우 응용 프로그램을 시작합니다.

Autokey - 실행 중인 경우 응용 프로그램 창에 초점을 맞추고, 그렇지 않은 경우 응용 프로그램을 시작합니다.

pcmanfm다음과 같이 processID를 얻으려고합니다.

pgrep -f "pcmanfm"

실행 되지 pcmanfm않으면 위 명령은 예상대로 아무것도 반환하지 않습니다.

그러나 Python에서 명령을 실행하면 pcmanfm실행 중이 아닌 경우에도 프로세스 ID가 반환됩니다.

processID = os.system('pgrep -f "pcmanfm"')

또한 python3 프롬프트에서 위 명령을 여러 번 실행하면 매번 다른 프로세스 ID가 반환됩니다. 그동안 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교체하여 작동하게 했습니다(@they의 제안). -nx또한 예상되는 빈 출력으로 인해 발생하는 자동 키 예외를 무시하기 위해 몇 가지 예외 처리를 추가했습니다. 또한 더 넓은 범위의 명령/응용 프로그램을 제공할 수 있도록 (보다 유연한) 기능으로 변환했습니다.

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.


설명하다:

명령을 실행하기 위해 실행된 셸의 프로세스 ID를 얻을 수 있습니다. 각각에 사용됩니다 system.exec_command.

예를 들어 실행 sh -c 'pgrep -af nonexistent'하고 출력을 확인하십시오. 당신은 다음과 같은 것을 얻을 수도 있습니다

11300 sh -c pgrep -af nonexistent

기존 명령을 사용하여 쉘에서도 한 줄을 얻었습니다.

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 또는 셸 프로세스의 PID를 추출할 수 있습니다.

옵션을 사용하면 프로세스 이름뿐만 아니라 전체 명령줄을 검색하도록 -f명시적으로 지시할 수 있습니다 . pgrep그러면 쉘의 명령줄 인수에서 문자열을 찾을 수 있습니다.

이것이 없으면 -f쉘 프로세스를 얻을 수 없습니다.

$ 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"])

관련 정보