示例脚本如下:
#!/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
)并且只有sudo
ed 版本会继续前进。如果后面的行exec sudo
被执行,则意味着 shell 甚至无法启动sudo
,并且确实出了问题。
如果用户被授权运行脚本,sudo
可能会也可能不会请求密码;如果输入了错误的密码或用户无权以 root 身份运行脚本,sudo
则会显示标准错误消息。
如果成功,sudo
将再次启动脚本,现在以 root 权限运行。该if
表达式现在将跳过该exec sudo...
步骤并继续执行脚本的其余部分。
所以流程将是:
- 父级:用户运行脚本的命令行会话
- child:最初以用户身份运行脚本的 shell,但
sudo
由于以下原因而变成exec
- 孙子:以 root 身份运行脚本的 shell。