58

我想编写一个 shell 脚本来自动执行一系列命令。问题是某些命令必须以超级用户身份运行,而某些命令不得以超级用户身份运行。到目前为止我所做的是这样的:

#!/bin/bash

command1
sudo command2
command3
sudo command4

问题是,这意味着在提示输入密码之前必须等到 command1 完成,然后,如果 command3 花费的时间足够长,他们将不得不等待 command3 完成。如果这个人可以站起来走开,然后一个小时后回来完成,那就太好了。例如,下面的脚本就有这个问题:

#!/bin/bash

sleep 310
sudo echo "Hi, I'm root"
sleep 310
sudo echo "I'm still root?"

我怎样才能做到这一点,以便用户可以在一开始就输入他们的密码一次,然后走开?

更新:

感谢您的回复。我在 Mac OS X Lion 上运行并运行了 Stephen P 的脚本并得到了不同的结果:(我还添加了 $HOME)

pair@abbey scratch$ ./test2.sh
uid is 501
user is pair
username is 
home directory is /Users/pair
pair@abbey scratch$ sudo ./test2.sh 
Password:
uid is 0
user is root
username is root
home directory is /Users/pair
4

4 回答 4

52

文件sutest

#!/bin/bash
echo "uid is ${UID}"
echo "user is ${USER}"
echo "username is ${USERNAME}"

运行它:`./sutest' 给我

uid is 500
user is stephenp
username is stephenp

但使用 sudo:sudo ./sutest给出

uid is 0
user is root
username is stephenp

因此,当以 sudo 运行时,您保留 $USERNAME 中的原始用户名。这导致了一个类似于其他人发布的解决方案:

#!/bin/bash
sudo -u ${USERNAME} normal_command_1
root_command_1
root_command_2
sudo -u ${USERNAME} normal_command_2
# etc.

只需 sudo 首先调用您的脚本,它会提示输入密码一次。


我最初在 Linux 上写了这个答案,它与 OS X 确实有一些差异

OS X(我在 Mountain Lion 10.8.3 上对此进行测试)SUDO_USER 在您运行 sudo 时有一个环境变量,它可以用来代替USERNAME上面,或者为了更跨平台,脚本可以检查是否 SUDO_USER已设置并使用它,如果已设置,则使用 USERNAME。

更改 OS X 的原始脚本,它变成...

#!/bin/bash
sudo -u ${SUDO_USER} normal_command_1
root_command_1
root_command_2
sudo -u ${SUDO_USER} normal_command_2
# etc.

使其跨平台的第一次尝试可能是……

#!/bin/bash
#
# set "THE_USER" to SUDO_USER if that's set,
#  else set it to USERNAME if THAT is set,
#   else set it to the string "unknown"
# should probably then test to see if it's "unknown"
#
THE_USER=${SUDO_USER:-${USERNAME:-unknown}}

sudo -u ${THE_USER} normal_command_1
root_command_1
root_command_2
sudo -u ${THE_USER} normal_command_2
# etc.
于 2012-04-19T00:53:25.097 回答
10

您应该以超级用户身份运行整个脚本。如果您想以非超级用户身份运行某些命令,请使用 sudo 的“-u”选项:

#!/bin/bash

sudo -u username command1
command2
sudo -u username command3
command4

以 root 身份运行时,sudo 不要求输入密码。

于 2012-04-19T00:35:49.460 回答
3

如果你使用这个,也要检查man sudo

#!/bin/bash

sudo echo "Hi, I'm root"

sudo -u nobody echo "I'm nobody"

sudo -u 1000 touch /test_user
于 2012-04-19T00:37:51.287 回答
3

好吧,你有一些选择。

您可以将 sudo 配置为不提示输入密码。由于存在安全风险,不建议这样做。

您可以编写一个期望脚本来读取密码并在需要时将其提供给 sudo,但这既笨重又脆弱。

我建议将脚本设计为以 root 身份运行,并在不需要时放弃其权限。只需将它sudo -u someotheruser command用于不需要 root 的命令。

(如果他们必须以用户调用脚本的身份专门运行,那么您可以让脚本保存 uid 并通过 sudo 调用第二个脚本,并将 id 作为参数,因此它知道向谁 su ..)

于 2012-04-19T00:40:09.830 回答