我在centos7上有一个bash脚本,我需要以不同的用户身份执行一些命令。但它似乎sudo
在函数外部按预期工作,但在 bash 函数内部不起作用。我运行脚本为ssh [email protected] 'bash -s' < script.sh
test(){
sudo -Eu root bash
echo "inside $(whoami)"
# other commands ...
}
test
sudo -Eu root bash
echo "outside $(whoami)"
运行这个作为
ssh [email protected] 'bash -s' < script.sh
印刷:
outside root
inside centos
root
给出了用户作为可重复性的示例。这个结果背后的原因是什么?如何以不同用户身份在函数内执行一堆命令?
答案1
不要这样做。
以错误的顺序获得两行输出应该暗示出现了问题。
当您使用执行脚本时
ssh [email protected] 'bash -s' < script.sh
发生以下情况:
- 该脚本被传递到
bash -s
shell 标准输入流。 - 该脚本定义该
test
函数并调用它。 sudo bash
函数中的命令启动 root shell 。- 这个shell继承了标准输入流,也就是脚本。
- 根 shell 继续从函数调用后的位置读取脚本。这样做是因为这是流此时所在的位置。
现在您有了一个从函数内部启动的根 shell test
,它在test
调用后执行指令。
- 它启动第二个根shell,它继承标准输入流(即shell 脚本流)。
您现在有一个centos
执行 root shell 的 shell,正在执行 root shell。
- 第二个 root shell 执行
echo "outside $(whoami)"
输出outside root
,这是脚本的最后一行。 - 没有更多内容可读取,因此第二个 root shell 终止。
- 第一个 root shell 也是如此。
- 原始
bash -s
shell 执行echo "inside $(whoami)"
(因为它是之前开始执行的函数的一部分),输出inside centos
. - shell 函数调用退出,并且由于两个根 shell 已读取脚本的其余部分,因此原始 shell 不再需要读取任何内容并终止。
sudo
严格用于执行另一个命令(或启动交互式 shell)。用户的更改仅适用于其他命令。当命令终止时,您将恢复为原始用户。您不能sudo
在脚本中间使用“切换到另一个用户”,然后以该其他用户的身份运行该脚本的一部分(当然,除非您故意地编写你的脚本,以上面解开的奇怪方式执行,但这种编码属于混淆代码竞赛)。
要以 root 身份在脚本中执行一组命令,您必须将这些命令提供给调用sudo
。例如:
sudo bash -c 'echo "Now running as $USER"; echo "whoami outputs $(whoami)"'
命令退出后sudo bash -c
,您将恢复为原始用户。总是。
答案2
您需要在启动的 shell 中执行命令sudo
。
$ f() {
sudo -Eu root bash -c whoami
}
$ f
root