为什么 shell 脚本中的“sudo su”不以 root 身份运行脚本的其余部分?

Hon*_*hen 47 shell root su sudo shell-script

示例脚本可以如下所示:

#!/bin/bash
sudo su
ls /root
Run Code Online (Sandbox Code Playgroud)

当使用./test.sh作为普通用户,而不是运行ls超级用户和出口,它切换到根; 当我注销时,它ls /root以普通用户身份执行。

谁能告诉我有关它的机制?

Joh*_*han 56

脚本中的命令一一独立执行。脚本本身作为脚本中所有命令的父进程,是另一个独立进程,su 命令不会也不能将其更改为 root:su 命令创建一个具有 root 权限的新进程。

su 命令完成后,仍以同一用户身份运行的父进程将执行脚本的其余部分。

您想要做的是编写一个包装脚本。特权命令进入主脚本,例如~/main.sh

#!/bin/sh
ls /root
Run Code Online (Sandbox Code Playgroud)

包装脚本调用具有 root 权限的主脚本,像这样

#!/bin/sh
su -c ~/main.sh root
Run Code Online (Sandbox Code Playgroud)

要启动此过程,您需要运行包装器,它会在将用户切换到 root 用户后启动主脚本。

这种包装器技术可用于将脚本变成围绕其自身的包装器。基本上检查它是否以root身份运行,如果不是,请使用“su”重新启动。

$0 是一种让脚本引用自身的便捷方式,而 whoami 命令可以告诉我们我们是谁(我们是 root 吗?)

所以带有内置包装器的主脚本变成

#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root
Run Code Online (Sandbox Code Playgroud)

注意exec的使用。它的意思是“replace this program by”,这实际上结束了它的执行并启动了由su启动的新程序,以root身份从顶部运行。替换实例是“root”,因此它不会执行 || 的右侧

  • 也许它有点过时,但我喜欢每个可执行文件的绝对路径,所以有人不能将 ~/main.sh 脚本更改为邪恶的东西。攻击脚本的 USER 部分 (2认同)
  • 您可能还想通过包含对 $* 的引用来捕获传递给它的参数 (2认同)

小智 22

在脚本中使用以下内容。

sudo su <<HERE
ls /root
HERE
Run Code Online (Sandbox Code Playgroud)

HERE 块之间的代码将以 root 身份运行。

  • `sudo su` 正在调用两个程序。使用 `sudo -s &lt;&lt;HEREDOC` 或 `su user &lt;&lt;HEREDOC` ...愚蠢的 5 分钟限制。 (8认同)

Ban*_*uin 6

没有进一步的参数su将运行 root 的登录 shell。这就是脚本的第一行实际所做的。当您退出时,登录 shell 关闭,su 返回并且您的脚本继续执行,即第二行:ls /root。我认为你可以简单sudo ls /root地做你想做的事。