python - 无法使用 Subprocess 模块成功解析和运行长命令
问题描述
我正在尝试通过在 Mac 上的终端中运行一系列命令来在我的机器上实现端口转发,这些命令可以在此处找到。我正在尝试通过subprocess
在 Python 中使用来运行后一个链接中列出的端口映射命令。
我试图运行的命令subprocess
是:
echo "
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
" | sudo pfctl -ef -
我对上述命令的 Python 实现:
from subprocess import Popen, PIPE
commands = ['echo', '"rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080"\n', '|', 'sudo', 'pfctl', '-ef', '-']
p = Popen(['sudo', '-S']+commands, stdin=PIPE, stderr=PIPE, universal_newlines=True)
print(p.communicate('root_password\n')[1])#be able to read password for sudo from stdin
但是,这个 Python 脚本不起作用,因为当我运行sudo pfctl -s nat
以在我的机器上显示所有端口转发规则时,我的预期输出
rdr pass inet proto tcp from any to any port = 80 -> 127.0.0.1 port 8080
不显示到外壳。
然而,运行
echo "
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
" | sudo pfctl -ef -
确实产生
rdr pass inet proto tcp from any to any port = 80 -> 127.0.0.1 port 8080
运行显示命令后sudo pfctl -s nat
。
如何subprocess
改进我的实现以便正确输出规则列表?
编辑:奇怪的是,我可以sudo pfctl -s nat
使用运行显示命令subprocess
p = Popen(['sudo', '-S']+'pfctl -s nat'.split(), stdin=PIPE, stderr=PIPE, universal_newlines=True)
print(p.communicate(f'myrootpassword\n')[1]))
sudo pfctl -s nat
实现与在 shell 本身中运行时相同的输出。
我正在 macOS Sierra 10.12.5 上运行命令和 Python 尝试。
解决方案
您正在尝试使用Popen()
执行多个命令的管道,但它不起作用。这是一个外壳功能。
我相信您需要Popen()
多次调用,每个命令一次,并明确地将它们的标准输入/标准输出相互挂钩。
推荐阅读
- sql - 带有 Varchar 的 IN 不起作用 sql server
- java - 如何在 android 中以编程方式在 SVG 上设置和获取色调颜色?
- tensorflow - 在哪些情况下我们使用属性 trainable_variables 而不是 trainable_weights,反之亦然 TF2 中的 tf.keras.Model?
- java - eclipse中的链接源文件夹在其他编辑器和终端中不起作用
- php - 无法从处理程序类 laravel 获取会话消息
- android - 当 Json 内容以对象 ({) 开头时,我无法使用 Kotlin 访问
- amazon-web-services - 将资产从 Cloudinary 迁移到 AWS
- c# - 如何在 EFCORE 的 SqlParameter[] 方法中赋值?
- sql - TSQL - 从随机文本创建一个 GUID,然后从该 GUID 取回原始文本值
- compare - Pinescript - 具有百分比变化功能的“比较”指标仅采用最后一根柱线数据