1

我有一个 Python 脚本,比方说install.py(我作为 sudo 运行),在 OS X 上安装 homebrew、Xcode、pip、ruby、swig,最终还有 salt。问题是运行和安装所有东西(Xcode CLI in partituclar)需要很长时间才能运行,以至于 sudo 超时,需要另一个管理员凭据提示。

事情就是这样。作为 的一部分install.py,在开始所有安装之前,我首先通过打开一个子进程创建一个本地管理员用户并使用:

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 的安装位置,现在我们开始自制软件:

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

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

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. 返回的是:

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

此时,我认为我的新管理员帐户设置不正确。退出脚本,然后尝试使用我刚刚创建的新管理员帐户:

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

看起来很熟悉。

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

Defaults    timestamp_timeout=15

这应该可以解决它......但我觉得这里应该有一个更好的解决方案,我没有看到或尚未探索。如果我们可以将它作为 python 子进程运行prexec_fn,那将是理想的。

4

1 回答 1

0

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

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

于 2013-09-13T22:23:53.167 回答