在 PyCharm 中使用子进程执行 sudo 命令
Posted
技术标签:
【中文标题】在 PyCharm 中使用子进程执行 sudo 命令【英文标题】:Execute sudo commands with subprocess in PyCharm 【发布时间】:2018-12-15 21:44:05 【问题描述】:我正在尝试从 Python 3 执行 sudo 命令。我通常使用子进程在 Python 中运行我的终端命令。已经有很多问题在讨论这个话题,但我找不到任何适合我的解决方案。
我的操作系统是 Ubuntu 18.04,我正在使用 Python 3.6 和 PyCharm。
无论我如何尝试,我都无法使用子进程输入密码。我的脚本在尝试输入 sudo 密码时总是卡住。在第一个答案之后,我意识到问题不在于我的代码,问题在于 PyCharm。从控制台运行它们时,以下所有尝试都可以正常工作,但是当我从 PyCharm 解释器运行它们时它们会卡住。以下是我尝试过的所有版本:
尝试 1:
import subprocess
sudo_password = b"myPassword\n"
print(subprocess.check_output('sudo -S echo success', shell=True, input=sudo_password)) #stuck here
这似乎是解决问题的最简单方法,但不知何故子进程无法输入密码,它总是会卡住,直到我终止进程。
尝试 2:
import subprocess
sudo_password = b"myPassword\n"
proc = subprocess.Popen('sudo -S echo success', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.stdin.write(sudo_password)
proc.stdin.flush()
print(proc.stdout.readlines()) #stuck here
在我的第二次尝试中,我尝试自己处理流媒体,但这似乎也不起作用。程序在读取 outstream 的行时会卡住。当我中止代码时,我收到以下错误消息,表明控制台已提示输入密码,但不知何故无法输入。
Traceback (most recent call last):
File "/home/anon/sudo.py", line 7, in <module>
[sudo] password for anon: print(proc.stdout.readlines()) #stuck here
KeyboardInterrupt
尝试 3:
我知道我可以将密码从终端输入 sudo 命令:
anon@anon:~$ echo myPassword | sudo -S echo success
[sudo] password for anon: success
所以我尝试使用子进程做同样的事情:
import subprocess
sudo_password = "myPassword"
print(subprocess.check_output("echo | sudo -S echo success".format(sudo_password), shell=True)) #stuck here
但这种方法又一次像所有其他方法一样陷入困境。
尝试 4:
import subprocess
import os
sudo_password = "myPassword"
with open("temp.sh", 'w') as file:
file.write("echo | sudo -S echo success".format(sudo_password))
print(subprocess.check_output("sh temp.sh", shell=True)) #stuck here
os.remove("temp.sh")
所以在我最后一次绝望的尝试中,我认为如果我将命令放入 shell 文件并使用子进程执行它,我可能会成功,因为我不会将任何 sudo 命令直接输入到子进程。当我自己在终端中尝试时,效果很好:
anon@anon:~$ sh temp.sh
[sudo] password for anon: success
但是 Python 脚本和以前一样卡在了同一个地方。
有谁知道这些尝试失败的原因以及我如何才能实现我的目标?在此先感谢:)
编辑:
有人给我链接了一篇关于这个主题的旧帖子,它使用 os 而不是 subprocess。 os 已被弃用,应该使用 subprocess 代替,这就是为什么我最初没有在这个问题中展示任何这些尝试,但是在使用 os 时它也会卡住:
import os
sudo_password = "myPassword"
p = os.system('echo | sudo -S echo success'.format(sudo_password)) #stuck here
编辑 2:
好的,现在我发现,如果您使用以下命令从终端运行脚本,我的所有尝试以及第一个答案中的建议实际上都会起作用:
anon@anon:~$ python3 checksudo.py
所以问题似乎出在我的解释器 PyCharm 上。这也是我的问题对this question 独一无二的原因,因为他们的问题不是来自他们的口译员。
是否有人对如何使代码在 PyCharm 中工作有任何建议,或者我是否应该从控制台运行我的所有脚本?感谢您抽出宝贵时间。
【问题讨论】:
***.com/questions/13045593/… 第三次尝试中似乎缺少.format(sudo_password)
。
Using sudo with Python script的可能重复
这是重复的,因为较早的问题称为“将 sudo 与 Python 脚本一起使用”,这正是您要问的。此外,那里的许多答案还包括使用子流程,而不是操作系统,这就是您说您忽略了旧问题的原因。
您是否考虑使用visudo
修复/etc/sudoers
文件以抑制密码提示?另外,由于 pexpect 旨在处理交互式 CLI (***.com/questions/39907546/…),您是否查看过 pexpect
而不是 subprocess?
【参考方案1】:
怎么样:
# coding=utf-8
from subprocess import Popen, PIPE
sudo_password = 'mypass'
command = 'echo success'.split()
p = Popen(['sudo', '-S'] + command, stdin=PIPE, stderr=PIPE,
universal_newlines=True)
sudo_prompt = p.communicate(sudo_password + '\n')[1]
print('Done!')
当然,请确保在代码中输入正确的密码。
【讨论】:
还是不行。即使输入正确的密码,它也会卡在最后一行。当我在最后添加 print(sudo_promt) 时,它永远不会到达。 我运行了这个精确的剪切和粘贴代码(仅更改密码)并获得了所需的“成功”输出。 你为什么要打印?阅读代码;你必须使用communicate
我添加了一个print('Done!')
,显示python代码没有被通信阻止。即使密码错误,只有实际的命令(回显成功)不起作用。
谢谢,如果您从控制台运行它们,您的建议以及我所有的尝试都会真正奏效。我的问题似乎是我的解释器 PyCharm。以上是关于在 PyCharm 中使用子进程执行 sudo 命令的主要内容,如果未能解决你的问题,请参考以下文章
Windows批处理 调用程序后 不等待子进程 父进程继续执行命令
如何使用 python 子进程模块将 sqlplus 作为 sudo 连接到 oracle 用户?