在一个shell脚本中使用su和sudo

6

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

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

现在它使用以下代码:

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

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

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

6个回答

6

不应该这样。如果脚本需要root权限,它应该以root身份运行。如何完成这个过程是用户的事情 -- 使用su、sudo或其他机制。

如果您担心安全问题,不想从root执行所有操作,您可以为这些部分放弃root权限。


zserge在下面的评论中解释说:“那是旧版本中使用的代码。现在我正在尝试从[安装]脚本中获取root权限,这样用户就不必重新启动它了。看起来更加用户友好。” 这似乎是一个公平的问题基础,而不是本质上的邪恶;-)。 - Tony Delroy
@Tony: 我的观点是这根本不友好。这是试图比用户更聪明的例子。在某些情况下,这可能有效,但更有可能会给用户带来问题。此外,你应该遵循最少惊喜原则。如果某个程序尝试在没有我的同意的情况下使用sudo获取root权限,我会感到惊讶(并且会向作者提出一些问题)。 - Roman Cheplyaka

3

没有一种绝对可靠的方法来完成这个任务,因为任何发行版都可以按照自己的方式放置文件。例如,Debian和Ubuntu经常将系统文件放置在与Red Hat不同的目录中。更容易的做法是根据已安装的操作系统自定义脚本。


2
您可以在/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用户。


这个脚本是一种安装程序 - 我不在我的主机上运行它,但其他用户在他们的机器上运行它。 - zserge
第二部分怎么处理呢?提前退出并提示他们以root身份运行脚本。 - gpojd
那是在旧版本中使用的代码。现在我正在尝试从脚本中获取root权限,这样用户就不必重新启动它了。看起来会更加用户友好。 - zserge
@zserge:您可以提示用户选择 - “1:切换到 root 用户并继续(需要 root 密码);2:使用 sudo 运行脚本(如果有权限);3:中止安装”。 - Tony Delroy

1
从这个文件中创建另一个.sh文件,将您原始的.sh文件命名为 -
su - oracle /u01/enlightics/Enlightiks/UploadFTP/ExportScript2.sh

0

检查是否安装了sudo

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

一种不错的方法。但是:机器上可能已经安装了sudo,但用户没有权限使用sudo来运行这个脚本。 - zserge
这并不重要,因为这样,sudo 将会失败,而不需要输入密码,然后你可以调用 su(只需观察 sudo true 的结果即可)。 - bitmask
也许我错了,但是虽然用户被允许运行true命令,但不能保证他能够运行我们的脚本。如果用户被允许使用密码运行程序,在执行sudo true时将会提示输入密码。我尽量避免不必要的密码提示。 - zserge
好的,“sudo true”是垃圾。确保您的脚本返回0(true),然后用sudo运行它。这样,用户只会被询问一次,如果他无法使用sudo运行您的脚本,您将会因为返回值而知道,以便您可以调用“su”。 - bitmask
我找不到更好的解决方案,但那仍然涉及要求用户密码,然后可能需要请求管理员权限密码:避免这种情况才是问题的关键。 - Tony Delroy

0
虽然这并没有完全回答你的问题,但值得注意的是,你可以使用以下命令检查是否安装了sudo软件包:
基于Debian的系统:
dpkg -s sudo

RPM基础系统:

rpm -q sudo

1
那么 Gentoo、Arch 或 Slackware 用户呢?在我看来,which sudo 是一种更通用的测试程序是否已安装的方法。 - zserge
那么,Free/Open/Net BSD、macOS、Illumos、HP/UX、Android和webOS呢?如果你必须依赖于某些东西,就依赖于POSIX.1吧。绝对不要依赖于特定平台的打包工具。 - ghoti
“hash somebinary”也是一种很好的查找二进制文件的方法,特别是如果您将再次调用该二进制文件,因为它会缓存路径以加快执行速度,但如果您预期失败并且只想要退出代码,则可能需要将所有输出重定向到/dev/null。 - dragon788

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接