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

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

示例脚本如下:

#!/bin/bash
sudo su
ls /root

./test.sh以普通用户使用时,改为ls超级用户运行并退出,切换到root;当我注销时,它ls /root以普通用户身份执行。

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

答案1

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

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

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

#!/bin/sh
ls /root

包装脚本使用 root 权限调用主脚本,如下所示

#!/bin/sh
su -c ~/main.sh root

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

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

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

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

#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root

注意exec的使用。它的意思是“将此程序替换为”,它有效地结束其执行并启动由 su 启动的新程序,以 root 身份从顶部运行。替换实例是“root”,因此它不会执行 || 的右侧

答案2

在脚本中使用以下内容。

sudo su <<HERE
ls /root
HERE

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

答案3

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

答案4

如果您需要一个以root权限运行的脚本,请将其放在它的开头:

if [ ! $(whoami)=”root” ]; then
    exec sudo ”$0” ”$@”
    echo ”Error: failed to execute sudo” >&2
    exit 1
fi

这将使用相同的参数重新执行脚本,但前缀为sudo.如果sudo命令成功启动,它将替换第一个脚本进程(因为exec)并且只有sudoed 版本会继续前进。如果后面的行exec sudo被执行,则意味着 shell 甚至无法启动sudo,并且确实出了问题。

如果用户被授权运行脚本,sudo可能会也可能不会请求密码;如果输入了错误的密码或用户无权以 root 身份运行脚本,sudo则会显示标准错误消息。

如果成功,sudo将再次启动脚本,现在以 root 权限运行。该if表达式现在将跳过该exec sudo...步骤并继续执行脚本的其余部分。

所以流程将是:

  • 父级:用户运行脚本的命令行会话
  • child:最初以用户身份运行脚本的 shell,但sudo由于以下原因而变成exec
  • 孙子:以 root 身份运行脚本的 shell。

相关内容