子进程 & Python 我做错了什么?

Subprocess & Python what am I doing wrong?

我对这个一无所知。尝试在 python 脚本中使用子进程通过 iw 抓取我的 wifi 信号。终端命令工作正常:

root@123da06:/app# iw dev wlan0 link | grep signal | awk '{print }'
-62

但在 python 中尝试 运行 时失败了:

root@123da06:/app# python3 sub.py
Traceback (most recent call last):
  File "sub.py", line 2, in <module>
    output_bytes = subprocess.check_output("iw dev wlan0 link | grep signal | awk '{print }'")
  File "/usr/local/lib/python3.8/subprocess.py", line 411, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/usr/local/lib/python3.8/subprocess.py", line 489, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/local/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: "iw dev wlan0 link | grep signal | awk '{print }'"

脚本再简单不过了:

import subprocess
output_bytes = subprocess.check_output("iw dev wlan0 link | grep signal | awk '{print }'")
output = output_bytes.decode("utf-8") 
print(f'Signal: {output}')

我做错了什么?

您 运行 在这里遇到的一件大事是 iw dev wlan0 link | grep signal | awk '{print }' 不是一个进程。

这是三个进程,通过管道连接:iw,其输出通过管道传输到 grep,其输出通过管道传输到 awk

值得注意的是,当你 运行 这个命令时创建这些管道的东西是 shell - bash,最有可能 - 它是根据你传递给它的命令这样做的.

但是,

Python 的子进程命令希望您将可执行文件的路径作为第一个参数传递。然后,您可以传递其他字符串以用作您正在 运行ning 的可执行文件的参数。那么,以 python 的方式做事,大致如下:subprocess.check_output("/usr/sbin/iw", "dev", "wlan0"...)。这就是 python 感到困惑的原因 - 您传递给它的大长字符串不是文件路径。

但是,您可以告诉 python 您正在使用参数 - 布尔值 shell arg.

向它传递一个很长的 shell 命令

试试这个:

# note the "shell=True" bit
output_bytes = subprocess.check_output("iw dev wlan0 link | grep signal | awk '{print }'", shell=True)

你应该会看到结果。 Python 会将您的命令交给 shell,后者将正确执行它,而不是尝试使用您传递给它的字符串作为可执行文件的文件名给 运行。