安装aur包的python脚本

2024-09-28 21:58:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试制作一个python脚本来安装aur包,比如googlechrome、sublime text等,用于archlinux的新版本。我可以很好地克隆git url,但是我在使用makepkg程序时遇到了问题。我不能以sudo的身份运行脚本,因为makepkg不允许sudo权限,因为它会对系统造成损害,但是我需要sudo权限来安装pacman。我将张贴我的功能到目前为止,如果有人能帮助我,我将不胜感激。如果我在谷歌上找不到答案的话,我会提前几个小时找到答案的

def clone_and_makepkg(package_name, aur_folder_path, password):
    git_url = "https://aur.archlinux.org/" + package_name + ".git"
    new_package_path = os.path.join(aur_folder_path, package_name)

    print("Cloning " + git_url + " to " + new_package_path)

    Popen(["git", "clone", git_url, new_package_path]).wait()

    os.chdir(new_package_path)

Tags: path答案namegit脚本url权限package
1条回答
网友
1楼 · 发布于 2024-09-28 21:58:41

选项1:以用户身份执行脚本,将pacman -U的权限提升到root用户

我认为这是个坏主意。脚本读取密码并在不安全的内存中拖拽一段时间,这有点低级,因为它们最终想以根用户身份执行某些东西。但是,如果你坚持的话,它的作用将类似于方案2。在

选项2:以根用户身份执行脚本,将git clonemakepkg的子进程降级为用户

您可以使用subprocess.Popenpreexec_fn选项,根据help(subprocess.Popen),它可以:

preexec_fn: (POSIX only) An object to be called in the child process just before the child is executed.

唯一棘手的事情就是交出论据。如果不需要这样做,我们可以在Popen()构造函数调用中将函数(os.setuid)声明为preexec_fn选项。不幸的是,当我们定义子流程时,它将被执行,而不是按预期运行它。因此,我们将最终降级主进程。在

所以我们必须定义一个小包装函数:

def demote():
    os.setuid(1000)

然后可以定义我们的子流程:

^{pr2}$

当然,这并不是一个好的方法-硬编码uid等等。但是,如果我们希望demote()接受参数,那么我们就回到原点了。因此,我们必须让它变得更加困难,并定义一个嵌套函数(函数中的函数),其中外部函数被调用来定义子进程,接受参数,定义uid和gid,并返回应用降级的内部函数。听起来很复杂?严格地说,您不必这样做,但是假设我们想要灵活,所以我们开始:

def demote(user_uid, user_gid):
    def apply_demotion():
        os.setgid(user_gid)
        os.setuid(user_uid)
    return apply_demotion

第二个选项是使用su -c (command) (user),可以使用os.system()函数从python调用它:

^{4}$

为了保持一致性,您可能希望使用相同的方法同时运行git clonemakepkg命令。在

一个有效的例子

import os
from subprocess import Popen
import glob
import sys

def clone_and_makepkg(package_name, aur_folder_path="/tmp/build/", uid=1000, gid=1000):

    """prepare urls and paths"""
    git_url = "https://aur.archlinux.org/" + package_name + ".git"
    new_package_path = os.path.join(aur_folder_path, package_name)

    """ensure the build directory exists and user has correct privileges to work there"""
    if not os.path.exists(aur_folder_path):
        os.mkdir(aur_folder_path)
        os.chmod(aur_folder_path, 0o777)

    """perform git clone"""
    print("Cloning " + git_url + " to " + new_package_path)
    Popen(["git", "clone", git_url, new_package_path], preexec_fn=demote(uid, gid)).wait()

    """change to make directory"""
    os.chdir(new_package_path)

    """run makepkg"""
    Popen("makepkg", preexec_fn=demote(uid, gid)).wait()

    """collect built packages"""
    built_packages = glob.glob(new_package_path + os.sep + "*.pkg.tar.xz")

    """install each package"""
    for package in built_packages:
        print("Installing package {}".format(package))
        os.system("pacman -U " + package + "  noconfirm")

def demote(user_uid, user_gid):
    def apply_demotion():
        os.setgid(user_gid)
        os.setuid(user_uid)
    return apply_demotion


if __name__ == "__main__":
    """Example call. Will by default install package 3to2 (This example does not have any further dependencies
       except for python. Which is evidently already installed. So this example is hassle-free. For 
       examples with dependencies, you may want to find a way to deal with those in the script.)"""
    pkgname = "3to2"
    if len(sys.argv) > 1:
        pkgname = sys.argv[1]
    clone_and_makepkg(package_name=pkgname)

相关问题 更多 >