[英]Python run both as user and sudo
I'm writing a python script to automatize the installation of some tools every time I create a VM and, since I'm not a bash fan I'm doing it with python.我正在编写一个 python 脚本,以便在每次创建 VM 时自动安装一些工具,并且由于我不是 bash 粉丝,所以我正在使用 python 来完成它。 The problem is that
apt
installations require sudo privileges, while pip
installations don't.问题是
apt
安装需要 sudo 权限,而pip
安装不需要。
I'm looking for a way to downgrade my privileges back to normal user's after all apt installations.在所有 apt 安装之后,我正在寻找一种将我的权限降级回普通用户的方法。
At the moment I tryed a pretty ugly oneliner like os.system(f"su {user} && ...")
or subprocess.Popen(...)
目前我尝试了一个非常丑陋的单行器,比如
os.system(f"su {user} && ...")
subprocess.Popen(...)
Is there a decent way?有没有靠谱的方法?
You can use a list of apt
commands with subprocess
or pexpect
.您可以将
apt
命令列表与subprocess
或pexpect
。 It can also prompt for a password if no password is provided using getpass
:如果使用
getpass
未提供密码,它也可以提示输入密码:
NOTE - Tested on Ubuntu 20.04 using Python 3.8.10
注意- 使用 Python 3.8.10 在 Ubuntu 20.04 上测试
NOTE - Updated to use and test pipes.quote - Thx, pts!
注意- 更新为使用和测试管道。引用 - 谢谢,点!
import pipes
import shlex
import subprocess
from getpass import getpass
import pexpect
sudo_password = '********'
# First command in double quotes to test pipes.quote - Thx, pts!
commands = ["apt show python3 | grep 'Version'",
'sudo -S apt show python3 | grep Version', ]
print('Using subprocess...')
for c in commands:
c = str.format('bash -c {0}'.format(pipes.quote(c)))
# Use sudo_password if not None or empty; else, prompt for a password
sudo_password = (
sudo_password + '\r'
) if sudo_password and sudo_password.strip() else getpass() + '\r'
p = subprocess.Popen(shlex.split(c), stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
output, error = p.communicate(sudo_password)
rc = p.returncode
if rc != 0:
raise RuntimeError('Unable to execute command {0}: {1}'.format(
c, error.strip()))
else:
print(output.strip())
print('\nUsing pexpect...')
for c in commands:
c = str.format('bash -c {0}'.format(pipes.quote(c)))
command_output, exitstatus = pexpect.run(
c,
# Use sudo_password if not None or empty; else, prompt for a password
events={
'(?i)password': (
sudo_password + '\r'
) if sudo_password and sudo_password.strip() else (
getpass() + '\r')
},
withexitstatus=True)
if exitstatus != 0:
raise RuntimeError('Unable to execute command {0}: {1}'.format(
c, command_output))
# For Python 2.x, use string_escape.
# For Python 3.x, use unicode_escape.
# Do not use utf-8; Some characters, such as backticks, may cause exceptions
print(command_output.decode('unicode_escape').strip())
Output:输出:
Using subprocess...
Version: 3.8.2-0ubuntu2
Version: 3.8.2-0ubuntu2
Using pexpect (and getpass)...
Version: 3.8.2-0ubuntu2
[sudo] password for stack:
Version: 3.8.2-0ubuntu2
Process finished with exit code 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.