为什么这个 bash 命令在我 运行 它通常在 shell 但通过 Python 的 Popen 失败时起作用?
Why does this bash command work when I run it normally in a shell but fail through Python's Popen?
我想用 python 在 Kali 中生成一个终端,然后发送操作终端 window。
所以我可以生成一个新终端并在 Python:
中获取它的 pid
from subprocess import Popen, PIPE, STDOUT, check_output
p1 = Popen(['x-terminal-emulator'])
print(f'pid: {p1.pid}') // 31700
然后将其传递给 xdotool
,例如:
xdotool search --pid 31700
标准输出:
90177537 // first code given isn't the one to use
88080390 // second one seems to work, not sure why
然后将其传递回 xdotool
:
xdotool windowfocus 88080390
成功!我可以移动 window,将其传递给输入等
但是当我尝试将所有这些组合到 Python 代码中时,xdotool search --pid 31700
命令失败:
from subprocess import Popen, PIPE, STDOUT, check_output
p1 = Popen(['x-terminal-emulator'])
print(f'pid: {p1.pid}')
window_id = check_output(['xdotool', 'search', '--pid', str(p1.pid)])
错误:
pid: 548
Traceback (most recent call last):
File "/mnt/c/Users/jonat/Documents/Github/net-vis/python/scanner.py", line 6, in <module>
window_id = check_output(['xdotool', 'search', '--pid', str(p1.pid)])
File "/usr/lib/python3.9/subprocess.py", line 424, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
File "/usr/lib/python3.9/subprocess.py", line 528, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['xdotool', 'search', '--pid', '548']' returned non-zero exit status 1.
我做错了什么?
我认为您遇到了竞争条件。在 x-terminal-emulator
进程开始 运行 和它实际启动 window 并且可以使用 xdotool
发现之间有一个间隔。只需在您的代码中添加一个短暂的等待即可使它对我有用:
import subprocess
import time
p1 = subprocess.Popen(['x-terminal-emulator'])
print(f'pid: {p1.pid}')
time.sleep(2)
window_id = subprocess.check_output(['xdotool', 'search', '--pid', str(p1.pid)])
或者不用睡眠,而是使用轮询循环等待 xdotool
成功,可能有某种超时:
import subprocess
import time
p1 = subprocess.Popen(['lxterminal'])
print(f'pid: {p1.pid}')
t_start = time.time()
while True:
try:
window_id = subprocess.check_output(['xdotool', 'search', '--pid', str(p1.pid)])
break
except subprocess.CalledProcessError:
t_delta = time.time() - t_start
if t_delta > 5:
raise
time.sleep(0.1)
print('got window id:', window_id)
第二种解决方案会给您更好的响应时间。
我想用 python 在 Kali 中生成一个终端,然后发送操作终端 window。
所以我可以生成一个新终端并在 Python:
中获取它的 pidfrom subprocess import Popen, PIPE, STDOUT, check_output
p1 = Popen(['x-terminal-emulator'])
print(f'pid: {p1.pid}') // 31700
然后将其传递给 xdotool
,例如:
xdotool search --pid 31700
标准输出:
90177537 // first code given isn't the one to use
88080390 // second one seems to work, not sure why
然后将其传递回 xdotool
:
xdotool windowfocus 88080390
成功!我可以移动 window,将其传递给输入等
但是当我尝试将所有这些组合到 Python 代码中时,xdotool search --pid 31700
命令失败:
from subprocess import Popen, PIPE, STDOUT, check_output
p1 = Popen(['x-terminal-emulator'])
print(f'pid: {p1.pid}')
window_id = check_output(['xdotool', 'search', '--pid', str(p1.pid)])
错误:
pid: 548
Traceback (most recent call last):
File "/mnt/c/Users/jonat/Documents/Github/net-vis/python/scanner.py", line 6, in <module>
window_id = check_output(['xdotool', 'search', '--pid', str(p1.pid)])
File "/usr/lib/python3.9/subprocess.py", line 424, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
File "/usr/lib/python3.9/subprocess.py", line 528, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['xdotool', 'search', '--pid', '548']' returned non-zero exit status 1.
我做错了什么?
我认为您遇到了竞争条件。在 x-terminal-emulator
进程开始 运行 和它实际启动 window 并且可以使用 xdotool
发现之间有一个间隔。只需在您的代码中添加一个短暂的等待即可使它对我有用:
import subprocess
import time
p1 = subprocess.Popen(['x-terminal-emulator'])
print(f'pid: {p1.pid}')
time.sleep(2)
window_id = subprocess.check_output(['xdotool', 'search', '--pid', str(p1.pid)])
或者不用睡眠,而是使用轮询循环等待 xdotool
成功,可能有某种超时:
import subprocess
import time
p1 = subprocess.Popen(['lxterminal'])
print(f'pid: {p1.pid}')
t_start = time.time()
while True:
try:
window_id = subprocess.check_output(['xdotool', 'search', '--pid', str(p1.pid)])
break
except subprocess.CalledProcessError:
t_delta = time.time() - t_start
if t_delta > 5:
raise
time.sleep(0.1)
print('got window id:', window_id)
第二种解决方案会给您更好的响应时间。