在 kill() 之后从子进程中检索一个值
Retrieve a value from subprocess after kill()
这是一个有点奇怪的项目,我试图使用一个子流程来跟踪我按下的键数以衡量我的工作效率。
目前我使用 Amazon Dash 按钮启动子进程,然后在第二次按下时终止进程。
def start_keylogger():
global process
process = subprocess.Popen(["sudo", "python", "test.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def stop_keylogger():
os.killpg(process.pid, signal.SIGUSR1)
process.wait()
key_press_count = process.stdout.read()
return key_press_count
从那里我的键盘记录器还没有充实,但我想我想使用 sys.exit()
或 exit()
到 return 按键次数。
def exit_and_return_counter():
sys.stdout.write(current_keypress_counter)
exit()
if __name__ == '__main__':
signal.signal(signal.SIGUSR1, exit_and_return_counter)
try:
while 1:
main_loop()
except KeyboardInterrupt:
sys.exit()
最初我尝试使用 process.returncode
,但它只 returned 1
,我假设成功退出代码。而且我不能使用 stdout, stderr = process.communicate()
除非我想在第二次按下亚马逊按钮后保持键盘记录器一会儿。
简直运行
process.wait()
在 os.killpg(process.pid, signal.SIGUSR1)
之后。这等待进程结束和 returns 状态代码。因为你刚刚杀死它,所以它不会阻塞太久。捕获 USR1 信号并使用 sys.exit
更改从 child 返回的代码应该有效。
即使在 child 被杀死后,您也应该能够使用 process.stdout.read()
读取标准输出,因为为 inter-process 通信创建的管道至少与Popen object process
存在。
虽然不是一个优雅的答案,但使用 process.send_signal(signal.SIGUSR1)
有效(如 @cg909 所述)。在停止方法中我们有:
def stop_keylogger():
process.send_signal(signal.SIGUSR1)
process.wait()
return process.stderr.read()
然后在键盘记录器中处理信号:
def exit_and_return_counter(*args):
sys.stdout.write('%s'%counter)
exit()
if __name__ == '__main__':
signal.signal(signal.SIGUSR1, exit_and_return_counter)
try:
while 1:
main_loop()
except KeyboardInterrupt:
sys.exit()
您可以使用 SIGINT
信号(Ctrl+C 在终端中)向进程发出信号以打印统计信息和出口。您可以使用 KeyboardInterrupt
异常处理程序处理 SIGINT
:
#!/usr/bin/env python
#file: keylogger.py
import random
import time
counter = 0
def mainloop()
global counter
while True:
counter += 1
time.sleep(random.random())
if __name__ == '__main__':
try:
mainloop()
except KeyboardInterrupt: # on SIGINT
print(counter)
这是对应的控制器:
#!/usr/bin/env python3
import os
import signal
from subprocess import Popen, PIPE, DEVNULL
process = None
def start_keylogger():
global process
stop_keylogger(expect_process_running=False)
process = Popen(["python", "-m", "keylogger"], stdout=PIPE, stderr=DEVNULL,
preexec_fn=os.setpgrp)
def stop_keylogger(expect_process_running=True):
global process
if process is not None and process.poll() is None:
os.killpg(process.pid, signal.SIGINT)
counter = int(process.communicate()[0])
process = None
return counter
if expect_process_running:
raise RuntimeError('keylogger is not running')
当您在终端中 运行 keylogger.py
时(对于 testing/debugging),您可以通过按 Ctrl 来模拟发送 SIGINT
+C.
preexec_fn=os.setpgrp
创建一个单独的进程组。 os.killpg()
向它发送信号。如果您的 keylogger.py
在不需要 preexec_fn=os.setpgrp
时没有生成自己的子进程,并且调用 process.send_signal(signal.SIGINT)
而不是 os.killpg()
就足够了。
考虑 。
这是一个有点奇怪的项目,我试图使用一个子流程来跟踪我按下的键数以衡量我的工作效率。
目前我使用 Amazon Dash 按钮启动子进程,然后在第二次按下时终止进程。
def start_keylogger():
global process
process = subprocess.Popen(["sudo", "python", "test.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def stop_keylogger():
os.killpg(process.pid, signal.SIGUSR1)
process.wait()
key_press_count = process.stdout.read()
return key_press_count
从那里我的键盘记录器还没有充实,但我想我想使用 sys.exit()
或 exit()
到 return 按键次数。
def exit_and_return_counter():
sys.stdout.write(current_keypress_counter)
exit()
if __name__ == '__main__':
signal.signal(signal.SIGUSR1, exit_and_return_counter)
try:
while 1:
main_loop()
except KeyboardInterrupt:
sys.exit()
最初我尝试使用 process.returncode
,但它只 returned 1
,我假设成功退出代码。而且我不能使用 stdout, stderr = process.communicate()
除非我想在第二次按下亚马逊按钮后保持键盘记录器一会儿。
简直运行
process.wait()
在 os.killpg(process.pid, signal.SIGUSR1)
之后。这等待进程结束和 returns 状态代码。因为你刚刚杀死它,所以它不会阻塞太久。捕获 USR1 信号并使用 sys.exit
更改从 child 返回的代码应该有效。
即使在 child 被杀死后,您也应该能够使用 process.stdout.read()
读取标准输出,因为为 inter-process 通信创建的管道至少与Popen object process
存在。
虽然不是一个优雅的答案,但使用 process.send_signal(signal.SIGUSR1)
有效(如 @cg909 所述)。在停止方法中我们有:
def stop_keylogger():
process.send_signal(signal.SIGUSR1)
process.wait()
return process.stderr.read()
然后在键盘记录器中处理信号:
def exit_and_return_counter(*args):
sys.stdout.write('%s'%counter)
exit()
if __name__ == '__main__':
signal.signal(signal.SIGUSR1, exit_and_return_counter)
try:
while 1:
main_loop()
except KeyboardInterrupt:
sys.exit()
您可以使用 SIGINT
信号(Ctrl+C 在终端中)向进程发出信号以打印统计信息和出口。您可以使用 KeyboardInterrupt
异常处理程序处理 SIGINT
:
#!/usr/bin/env python
#file: keylogger.py
import random
import time
counter = 0
def mainloop()
global counter
while True:
counter += 1
time.sleep(random.random())
if __name__ == '__main__':
try:
mainloop()
except KeyboardInterrupt: # on SIGINT
print(counter)
这是对应的控制器:
#!/usr/bin/env python3
import os
import signal
from subprocess import Popen, PIPE, DEVNULL
process = None
def start_keylogger():
global process
stop_keylogger(expect_process_running=False)
process = Popen(["python", "-m", "keylogger"], stdout=PIPE, stderr=DEVNULL,
preexec_fn=os.setpgrp)
def stop_keylogger(expect_process_running=True):
global process
if process is not None and process.poll() is None:
os.killpg(process.pid, signal.SIGINT)
counter = int(process.communicate()[0])
process = None
return counter
if expect_process_running:
raise RuntimeError('keylogger is not running')
当您在终端中 运行 keylogger.py
时(对于 testing/debugging),您可以通过按 Ctrl 来模拟发送 SIGINT
+C.
preexec_fn=os.setpgrp
创建一个单独的进程组。 os.killpg()
向它发送信号。如果您的 keylogger.py
在不需要 preexec_fn=os.setpgrp
时没有生成自己的子进程,并且调用 process.send_signal(signal.SIGINT)
而不是 os.killpg()
就足够了。
考虑