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


36

示例脚本可以如下所示:

#!/bin/bash
sudo su
ls /root

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

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


13
sudo su使我的眼睛受伤。
gelraen 2013年

之所以使用它,是因为人们对sudo的了解不够,因此,他们需要一种在有意破坏密码的root安全的系统上运行su的方法。但是,是的,sudo可“冗余化” su的使用。
Johan 2013年

1
sudo -s但是,您不能只使用吗?
Joe Z.

@Johan,我经常使用,sudo su因为我su比的选择更习惯sudo。我很了解sudo的选项,但是我可以更快地输入su的选项。但是,是的,我想这意味着我对sudo不够了解。
user606723 2013年

1
我刚刚检查了sudo手册页。看起来sudo -i类似于su -while sudo -s操作su(无破折号)
Johan

Answers:


49

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

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

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

#!/bin/sh
ls /root

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

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

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

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

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

因此,带有内置包装器的主脚本变为

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

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


1
首先,这是附录。如果我正在编写类似的脚本,则只需在开始时执行if语句,检查$ EUID,如果它不是零,则sudo本身并退出,否则继续执行脚本。
Bratchley

同意,我将更新答案进行解释。
约翰,

2
也许有点陈旧,但是我喜欢每个可执行文件的绝对路径,所以有人无法将〜/ main.sh脚本更改为邪恶的东西。攻击脚本的USER部分
artifex 2013年

2
您可能还想通过包含对$ *的引用来捕获传递给它的参数
Bratchley

@JoelDavis我总是碰到“如果参数中有空格字符该怎么办”的墙。我从未找到令人满意的解决方案。有一次,我写了什么,它需要和传递给最终的脚本是什么文件读取找到原来的论点论据的脚本里面放了它的参数到一个临时文件,每行一个参数,然后调用。
约翰

20

在脚本中使用以下内容。

sudo su <<HERE
ls /root
HERE

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


6
sudo su正在调用两个程序。使用sudo -s <<HEREDOCsu user <<HEREDOC...愚蠢的5分钟限制。
Johan 2013年

6

如果没有其他参数,su将为root运行登录shell。这就是脚本的第一行实际执行的操作。退出时,登录外壳关闭,su返回,脚本继续执行,即第二行:ls /root。我认为您可以简单sudo ls /root地做自己想做的事。


是的,我知道我可以为此做ls,但这只是一个示例。实际上,我需要用root特权做更多的事情:-)所以我更喜欢@Ankit的答案。
陈洪旭2013年

1

一旦您以超级用户的身份触发sudo su了一个新进程userid (euid=EUID),因此我们将在(pid=PID)与同一终端关联的不同进程ID上运行新的bash (tname=TTY)

说明

假设在触发后ps -A | grep bash您具有21460 pts/2 00:00:00 bash输出。现在,当您同时执行./test.sh这两个命令时sudo suls /root将被后台处理到PID 21460。执行后,当您再次root成为活动用户ps -A | grep bash时,您会注意到上正在运行一个新的bash PID say, 21570。从退出root bash将杀死新叉状的bash还原为user's bash并因此ls /root在释放提示之前执行假脱机命令。


如果使用su或sudo在bash(或其他任何地方)中是“持久的”,那么它将产生比解决的问题更多的问题。为了安全起见,您需要尽可能少地作为根。使用su和sudo(除了安全性!)的主要目的是使您仔细考虑需要root特权的地方。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.