请务必注意,每当您使用 sudo 运行脚本时,“用户上下文”或环境都会切换到 root。
但是 Teo 是什么意思?
好吧,我的年轻学徒,这意味着如果 padawan 用户使用 sudo 运行包含波浪号 (~) 的脚本,那么每当 bash 扩展 ~ 时,结果将是 /root而不是/home/<user>(即在本例中为/home/padawan),或者如果您创建目录或文件,则所有者和组将是root,而不是在本例中执行脚本的padawan,因为用户环境已切换。
例如,让我们检查一下这个脚本install-app.sh:
#!/bin/bash
ROOT_UID=0 # Only users with $UID 0 have root privileges.
E_NOTROOT=87 # Non-root exit error.
## Prevent the execution of the script if the user has no root privileges
if [ "${UID:-$(id -u)}" -ne "$ROOT_UID" ]; then
echo 'Error: root privileges are needed to run this script'
exit $E_NOTROOT
fi
...
mkdir -vp ~/app/init
touch config
...
touch /home/<user>/app/init/profile
service mysql start
...
如果我们使用sudo运行:
sudo install-app.sh
这将创建目录,config 文件将如下所示:
##
## ~ (/root)
drwxr-xr-x 17 root root 4096 Nov 23 20:45 ./
drwxr-xr-x 5 root root 4096 Nov 15 19:04 ../
...
drwxr-xr-x 3 root root 4096 Nov 25 14:30 app/
...
drwxr-xr-x 2 root root 4096 Nov 16 19:08 tmp/
## ~/app (/root/app)
drwxr-xr-x 3 root root 4096 Nov 25 14:30 ./
drwxr-xr-x 17 root root 4096 Nov 25 14:33 ../
drwxr-xr-x 2 root root 4096 Nov 25 14:33 init/
## ~/app/init (/root/app/init)
drwxr-xr-x 2 root root 4096 Nov 25 14:33 ./
drwxr-xr-x 3 root root 4096 Nov 25 14:30 ../
-rw-r--r-- 1 root root 0 Nov 25 14:33 config
## /home/<user>/app/conf
drwxr-xr-x 2 <user> <user> 4096 Nov 25 14:43 ./
drwxr-xr-x 3 <user> <user> 4096 Nov 25 14:30 ../
-rw-r--r-- 1 root root 0 Nov 25 14:43 profile
如你所知,她的剧本一团糟。现在<user> 无法访问profile 文件,没有sudo 也无法修改config。一开始看起来并不重要,但相信我,如果您的项目变得更大,有人会运行脚本并弄乱您的系统。
推荐
我的建议是:请求用户验证是否是 sudoer。然后,将sudo 添加到需要它的命令中。
将此更改应用于脚本将如下所示:
#!/bin/bash
E_NOTROOT=87 # Non-root exit error.
## Prevent the execution of the script if the user has no root privileges
## Check if is sudoer
if ! $(sudo -l &>/dev/null); then
echo 'Error: root privileges are needed to run this script'
exit $E_NOTROOT
fi
...
mkdir -vp ~/app/init
touch config
...
touch /home/<user>/app/init/profile
sudo service mysql start
...
此修改允许用户像这样运行脚本:
install-app.sh
将要求用户输入他的密码以验证是否为 sudoer。之后,mkdir -vp ~/app/init会在用户家创建文件:
/home/<user>/app/init
/home/<user>/app/init/config
/home/<user>/app/init/profile
另外,我建议获取用户 homer 目录并将其用作常量。
## Defines user home directory
USER_HOME_DIR=$(getent passwd ${SUDO_USER:-$USER} | cut -d: -f6)
...
mkdir -vp "$USER_HOME_DIR/app/init"
...