如何在不重新提示凭据的情况下运行长Python脚本 [英] How to run long Python script without re-prompt for credentials

查看:122
本文介绍了如何在不重新提示凭据的情况下运行长Python脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在OS X上有一个Python脚本,例如install.py(我以sudo运行),该脚本安装了自制程序,Xcode,pip,ruby,swig,并最终安装了盐.问题在于,运行和安装所有内容(partitionclar中的Xcode CLI)花费的时间太长,以致sudo超时,需要再次提示输入管理员凭据.

I have a Python script, let's say install.py (which I am running as sudo), on OS X that installs homebrew, Xcode, pip, ruby, swig, and, ultimately, salt. The problem is that running and installing everything (Xcode CLI in partituclar) takes so long to run, that sudo times out, requiring another prompt for admin credentials.

这是东西.作为install.py的一部分,在开始所有安装之前,我首先通过打开一个子进程并使用以下命令来创建本地管理员用户:

Here's the thing. As part of install.py, before kicking off all the installations, I first create a local admin user by opening a subprocess and use:

make_admin_account = {
    "mkdir -p /Users/%(accountname)s",
    "sudo dscl . -create /Users/%(accountname)s",
    "sudo dscl . -create /Users/%(accountname)s UserShell /bin/bash",
    "sudo dscl . -create /Users/%(accountname)s RealName \"%(fullname)s\"",
    "sudo dscl . -create /Users/%(accountname)s UniqueID \"%(uid)s\"",
    "sudo dscl . -create /Users/%(accountname)s PrimaryGroupID 80",
    "sudo dscl . -create /Users/%(accountname)s NFSHomeDirectory /Users/%(accountname)s",
    "sudo dscl . -passwd /Users/%(accountname)s \"%(password)s\"",
    "sudo dscl . -append /Groups/admin GroupMembership%(accountname)s",
    "sudo dscl . -append /Groups/_appserveradm GroupMembership %(accountname)s",
    "sudo dscl . -append /Groups/_appserverusr GroupMembership %(accountname)s",
    "sudo chown -R %(accountname)s /Users/%(accountname)s",
    "sudo createhomedir -c -u %(accountname)s"
}

所以,现在我们有了一个本地管理员帐户.现在非常简单,运行每个安装程序.让我们跳到安装Xcode CLI的位置,现在我们开始自制软件:

So, now we have a local admin account. Pretty simply now, run through each of the installers. Let's jump ahead to where Xcode CLI had been installed, now we're kicking off homebrew:

print("Install Homebrew")
execute("sudo -H -u %s ruby homebrew_ruby" % accountname)

(execute()只是一个调用subprocess.Popen()的简单函数).一旦遇到sudo,它就会再次要求管理员凭据.这不是所需的行为.那么,如何将preexec_fn传递给子进程并以新创建的管理员帐户运行?

(execute() is just a simple function that's calling subprocess.Popen()) As soon as it encounters sudo, it wants admin credentials again. This is not desired behavior. So, how about passing a preexec_fn to the subprocess and running as the newly created admin account?

def demote(user_uid, user_gid):
    def result():
        os.setgid(user_gid)
        os.getuid(user_uid)
    return result


preexec_fn = demote(pwd.getpwnam(accountname).pw_uid, pwd.getpwnam(accountname).pw_gid)

execute("ruby homebrew_ruby", preexec_fn=preexec_fn)

同样,execute只是接受preexec_fn参数并将其传递给subprocess.Popen.返回的是:

Again, execute is just taking the preexec_fn argument and passing it to subprocess.Popen. What's returned is:

shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
chdir: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
chdir: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
job-working-directory: error retrieving current directory: getcwd: cannot access parent directories: Permission denied

在这一点上,我认为我的新管理员帐户设置不正确.退出脚本,然后尝试使用刚刚创建的新管理员帐户:

At this point, I'm thinking my new admin account is setup incorrectly. Exit script, and try su'ing to the new admin account I had just created:

shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied

看起来很熟悉.

因此,我想用一句话来表达:我正在寻找一种方法,以防止较长的Python脚本在默认5分钟内超时后提示管理员输入凭据.我可以编辑/etc/sudoers:

So, to put my desire into a sentence: I'm looking for a way to keep a long Python script from prompting for admin creds after it times out in the default 5 minutes. I know that I could just edit /etc/sudoers:

Defaults    timestamp_timeout=15

应该解决它...但是我觉得这里应该有一个更好的解决方案,要么我看不到,要么还没有探索过.如果我们可以使用prexec_fn将其作为python子进程运行,那将是理想的选择.

That ought to fix it...but I feel like there should be a better solution here that either I'm not seeing or haven't yet explored. If we could run it as a python child process with prexec_fn, that would be ideal.

推荐答案

在Python中,检查您的os.getcwd(),您可能是从一个时髦的地方奔跑的.

In Python, check your os.getcwd(), you're probably running from a funky place.

尝试将cwd='/tmp'传递给process.Popen().每个人都有权/tmp

Try passing cwd='/tmp' to process.Popen(). Everyone has permissions to /tmp!

这篇关于如何在不重新提示凭据的情况下运行长Python脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆