shell 脚本中的 su 和 sudo

Posted

技术标签:

【中文标题】shell 脚本中的 su 和 sudo【英文标题】:su and sudo in a shell script 【发布时间】:2011-04-20 20:45:23 【问题描述】:

有一个需要root权限才能执行的shell脚本(/bin/sh,不是bash)。

如果它由普通用户运行,它应该要求用户输入密码以获取 root 访问权限并重新运行。

现在它使用以下代码:

if [ $(id -u) -ne 0 ]; then su root -- $0 $@ ; ... fi

这很好用,但是有些操作系统(例如 Ubuntu)根本没有 root 密码。另一方面,很多系统使用 sudo 来获得 root 权限。

问题是:脚本如何检测是使用su还是sudo而不要求用户输入太多密码(例如输入sudo密码,如果失败-运行su)。

【问题讨论】:

【参考方案1】:

不应该。如果脚本需要 root 权限,它应该以 root 身份运行。用户将如何完成该任务是用户的事——使用 su、sudo 或其他一些机制。

如果您担心安全问题并且不想从 root 执行所有操作,您可以删除这些部分的 root 权限。

【讨论】:

zserge 下面的评论解释说“这是旧版本中使用的代码。现在我正在尝试从 [installation] 脚本中获取 root 权限,因此用户不必重新启动它。似乎更人性化一点”。似乎是一个问题的公平基础,而不是天生的邪恶;-)。 @Tony:我的意思是它对用户友好。这是一个试图比用户更聪明的例子。在某些情况下,这可能有效,但更有可能给用户带来问题。你也应该遵循最小惊喜的原则。如果某些程序在未经我同意的情况下尝试使用 sudo 获取 root 权限,我会感到惊讶(并且会对作者提出一些问题)。【参考方案2】:

这样做没有万无一失的方法,因为任何发行版都可以按照它想要的任何方式放置文件。例如,Debian 和 Ubuntu 经常将系统文件放在 Red Hat 以外的目录中。为安装它的操作系统定制脚本要容易得多。

【讨论】:

【参考方案3】:

您可以在 /etc/sudoers 中设置不需要 sudo 密码的帐户:

yourusername ALL=(ALL) NOPASSWD: ALL

如果您不想这样做,可以强制他们以 root 身份运行脚本。在 shell 脚本的顶部添加类似这样的内容:

if [ "$UID" -ne 0 ]; then
    echo "You must be root to run this script"
    exit 1
fi

这样,用户可以通过选择(su 或 sudo)成为 root。

【讨论】:

这个脚本是一种安装程序——我不在我的主机上运行它,但其他用户在他们的机器上运行它。 第二部分呢?提前退出并提示他们以 root 身份运行脚本。 这是旧版本中使用的代码。现在我正在尝试从脚本中获取 root 权限,因此用户不必重新启动它。似乎更人性化了一点 @zserge:您可能会提示用户 - “1:su 到 root 并继续(您需要 root 密码;2:使用 sudo 运行脚本(如果有权限);3:中止安装” 【参考方案4】:

从此文件再创建一个 .sh 文件,调用您原来的 .sh 文件,例如 -

su - oracle /u01/enlightics/Enlightiks/UploadFTP/ExportScript2.sh

【讨论】:

【参考方案5】:

检查sudo是否安装

SU='su'
which sudo > /dev/null && SU='sudo'

【讨论】:

一个不错的方法。但是:机器上可以安装sudo,但是用户没有权限用sudo运行这个脚本。 没关系,因为那样,sudo 将失败,无需询问密码,您可以调用su 代替(只需观察sudo true 的结果)。 也许我错了,但是虽然允许用户运行 true,但不能保证他可以运行我们的脚本。并且,如果允许用户使用密码运行程序,则在执行sudo true时会提示他。我尽量避免不必要的密码提示。 好吧,sudo true 是垃圾。确保 your 脚本返回 0 (true) 并使用 sudo 简单地运行它。然后,只询问用户一次,如果他不能 sudo 你的脚本,你会知道因为返回值,所以你可以调用su 我没有看到更好的东西,但这仍然涉及询问用户的密码,然后可能不得不询问 root 密码:避免这就是问题所在。【参考方案6】:

虽然这不能完全回答您的问题,但值得注意的是,您可以使用以下命令检查是否安装了 sudo 包:

基于 Debian 的系统:

dpkg -s sudo

基于 RPM 的系统:

rpm -q sudo

【讨论】:

gentoo、arch 或 slackware 用户呢?在我看来,which sudo 是一种更通用的方法来测试程序是否已安装。 那么,Free/Open/Net BSD、macOS、Illumos、HP/UX、android、webOS 呢?如果您必须依赖某些东西,请依赖 POSIX.1。当然不是特定于平台的打包工具。 hash somebinary 也是查找二进制文件的好方法,特别是如果您要再次调用二进制文件,因为它会缓存路径以便更快地执行,但您可能需要将所有输出重定向到/dev/null 如果您预计会失败并且只想要退出代码。

以上是关于shell 脚本中的 su 和 sudo的主要内容,如果未能解决你的问题,请参考以下文章

linux sudo时说找不到cd命令, 怎么解决

使用java中的jsch在linux中通过sudo命令执行shell脚本以启动服务

使用 sudo 运行时获取 shell 脚本

Linux中的sudoer详解

linux学习小记 (一 )

当使用“sudo su”时,jenkins在ssh上执行shell