我正在尝试在 python 中运行 sudo 来打开一个应用程序

Posted

技术标签:

【中文标题】我正在尝试在 python 中运行 sudo 来打开一个应用程序【英文标题】:I am trying to run sudo in python to open an application 【发布时间】:2017-01-14 02:04:47 【问题描述】:

例如,如果我想在我的 python 脚本上调用 synaptic,这就是我尝试过的,但我在使用 Popen 时遇到了错误。有没有办法用 sudo 而不是 gksu 来完成这项工作?我想使用这种方法在更大的程序中运行脚本。

process = subprocess.Popen("sudo synaptic", 'w', stdout=subprocess.PIPE, bufsize=1).write(password)
TypeError: __init__() got multiple values for keyword argument 'bufsize'

以下是我正在使用的内容

from PyQt4 import QtGui, QtCore
import os
import sys
import subprocess
# from mainwindow import Ui_MainWindow

class PasswordDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(PasswordDialog, self).__init__(parent)
        PasswordDialog.resize(self, 375, 130)
        PasswordDialog.setWindowTitle(self, "Enter Password")
        self.buttonOk = QtGui.QPushButton(self)
        self.buttonOk.setText("OK")
        self.buttonCancel = QtGui.QPushButton(self)
        self.buttonCancel.setText("Cancel")
        self.textEdit = QtGui.QLineEdit(self)
        self.textEdit.setFocus()

        self.label = QtGui.QLabel(self)
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setText("Enter your password to perform administrative Tasks")
        self.label.setWordWrap(True)
        self.label_2 = QtGui.QLabel(self)
        self.label_2.setText("Password")
        self.verticalLayout = QtGui.QVBoxLayout(self)
        self.verticalLayout.addWidget(self.label)
        self.horizontalLayout = QtGui.QHBoxLayout(self)
        self.horizontalLayout.addWidget(self.label_2)
        self.horizontalLayout.addWidget(self.textEdit)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout2 = QtGui.QHBoxLayout(self)
        self.horizontalLayout2.setAlignment(QtCore.Qt.AlignRight)
        self.horizontalLayout2.addWidget(self.buttonCancel)
        self.horizontalLayout2.addWidget(self.buttonOk)
        self.verticalLayout.addLayout(self.horizontalLayout2)
        self.buttonOk.clicked.connect(self.handleLogin)
        self.buttonCancel.clicked.connect(self.close)

    def handleLogin(self):
        password = self.textEdit.text()
        process = subprocess.Popen("sudo synaptic", 'w').write(password)
        #out = process.stdout.read(1)
        try:
            subprocess.check_call(process)
        except subprocess.CalledProcessError as error:
            print "error code", error.returncode, error.output



if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    login = PasswordDialog()

    if login.exec_() == QtGui.QDialog.Accepted:
        window = Window()
        window.show()
        sys.exit(app.exec_())

【问题讨论】:

你到subprocess.Popen的参数应该是一个列表,试试['sudo', 'synaptic'] 检查 Popen 的文档 - 也许其他参数已分配给 bufsize 见Popen:第二个参数w被分配给bufsize所以你有两个bufsize 'w' 参数被传递给buffsize 参数。 或者,如果你愿意,subprocess.Popen(['gksudo', 'synaptic']) 【参考方案1】:

我认为您应该使用communicate 将密码发送到sudo 命令。

试试这个:

import subprocess

with subprocess.Popen(["sudo", "synaptic"], stdout=subprocess.PIPE, bufsize=1) as process:
    process.communicate(password)
    process.wait()

process 的值应该是字节串……

【讨论】:

谢谢,如果输入了错误的密码,您知道如何捕获输出吗? @Tata​​kaiWasumi 提出一个新问题 我添加了shell=True,它修复了一些问题,但我收到了错误with subprocess.Popen(["sudo", "synaptic"], stdout=subprocess.PIPE, bufsize=1, shell=True) as process: AttributeError: __exit__ @Tata​​kaiWasumi 为什么不直接阅读Popen 的文档? 你说得对,我一直将 Popen 视为与 os.popen 相同。我会试试文档【参考方案2】:

您将错误的参数传递给Popen。文档在这里: https://docs.python.org/3/library/subprocess.html#popen-constructor

甚至更简单...只需使用subprocess 模块提供的call 函数:

subprocess.call(['sudo', 'synaptic'])

【讨论】:

但是我无法从 self.textEdit.text() 向 sudo 发送密码? @Tata​​kaiWasumi 这不是你问的问题。你问如何打电话给sudo synaptic。我提供了答案。这就是它在这里的工作方式。如果您有关于与衍生的子进程交互的后续问题,请提出一个新问题。 @CoreyGoldberg。为了公平起见,问题中的代码包括尝试向进程写入密码(尽管语法当然都是错误的,因为他们没有阅读 popen 文档)。

以上是关于我正在尝试在 python 中运行 sudo 来打开一个应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 PyCharm 中使用子进程执行 sudo 命令

Python sudo 在新的终端窗口中没有传递密码

如何在 Emacs 中运行 sudo 命令?

如何使用 python 子进程模块将 sqlplus 作为 sudo 连接到 oracle 用户?

用于安装 aur 包的 python 脚本

使用 sudo 运行时找不到命令