好的,情况是这样的:我正在使用 Python 和 wx (wxphoenix) 构建 macOS GUI 应用程序。用户可以使用 GUI(例如:script1
)启动文件删除过程(包含在script2
)。为了顺利运行script2
需要以 sudo 权限运行。
script2
将迭代一长串文件并删除它们。但我需要它与包含的 GUI 进行通信script1
每轮之后script1
可以更新进度条。
这是我的绝对最基本的形式当前工作设置看起来像这样:
Script1:
import io
from threading import Thread
import subprocess
import wx
# a whole lot of wx GUI stuff
def get_password():
"""Retrieve user password via a GUI"""
# A wx solution using wx.PasswordEntryDialog()
# Store password in a variable
return variable
class run_script_with_sudo(Thread):
"""Launch a script with administrator privileges"""
def __init__(self, path_to_script, wx_pubsub_sendmessage):
"""Set variables to self"""
self.path = path_to_script
self.sender = wx_pubsub_sendmessage
self.password = get_password()
Thread.__init__(self)
self.start()
def run(self):
"""Run thread"""
prepare_script = subprocess.Popen(["echo", password], stdout=subprocess.PIPE)
prepare_script.wait()
launch_script = subprocess.Popen(['sudo', '-S', '/usr/local/bin/python3.6', '-u', self.path], stdin=prepare_script.stdout, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(launch_script.stdout, encoding="utf-8"):
print("Received line: ", line.rstrip())
# Tell progressbar to add another step:
wx.CallAfter(self.sender, "update", msg="")
Script2:
import time
# This is a test setup, just a very simple loop that produces an output.
for i in range(25):
time.sleep(1)
print(i)
上述设置的工作原理是script1
接收的输出script2
实时并对其采取行动。 (所以在给定的例子中:每一秒之后script1
向进度条添加另一个步骤,直到达到 25 步)。
我想要实现什么= 不将密码存储在变量中,并使用 macOS 的本机 GUI 来检索密码。
但是当我改变时:
prepare_script = subprocess.Popen(["echo", password], stdout=subprocess.PIPE)
prepare_script.wait()
launch_script = subprocess.Popen(['sudo', '-S', '/usr/local/bin/python3.6', '-u', self.path], stdin=prepare_script.stdout, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(launch_script.stdout, encoding="utf-8"):
print("Received line: ", line.rstrip())
# Tell progressbar to add another step:
wx.CallAfter(self.sender, "update", msg="")
Into:
command = r"""/usr/bin/osascript -e 'do shell script "/usr/local/bin/python3.6 -u """ + self.path + """ with prompt "Sart Deletion Process " with administrator privileges'"""
command_list = shlex.split(command)
launch_script = subprocess.Popen(command_list, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(launch_script.stdout, encoding="utf-8"):
print("Received line: ", line.rstrip())
# Tell progressbar to add another step:
wx.CallAfter(self.sender, "update", msg="")
它停止工作,因为 osascript 显然在非交互式 shell 中运行 https://stackoverflow.com/a/49156646/4041795。这意味着script2
在完全完成之前不发送任何输出,导致进度条script1
拖延。
我的问题就变成了:我怎样才能确保使用 macOS 本机 GUI 来询问 sudo 密码,从而避免将其存储在变量中,同时仍然保持从交互式/实时流中的特权脚本捕获标准输出的可能性。
希望这是有道理的。
将不胜感激任何见解!