问题描述
我有一个可以运行为sudo script.sh
或pkexec script.sh
的脚本
从脚本的角度来看,如果脚本仅以名称script.sh
运行,如果脚本要求用户输入密码,那就更好了。
如何”embed”向pkexec
或sudo
请求以root权限运行整个脚本?
请注意,使用sudo sh -c
运行所有内容可能不是最佳解决方案,因为我在脚本中具有函数。
最佳方案
echo "$(whoami)"
[ "$UID" -eq 0 ] || exec sudo "$0" "$@"
例:
./test.sh
blade
[sudo] password for blade:
root
次佳方案
brand="My Software"
# Check that the script is running as root. If not, then prompt for the sudo
# password and re-execute this script with sudo.
if [ "$(id -nu)" != "root" ]; then
sudo -k
pass=$(whiptail --backtitle "$brand Installer" --title "Authentication required" --passwordbox "Installing $brand requires administrative privilege. Please authenticate to begin the installation.\n\n[sudo] Password for user $USER:" 12 50 3>&2 2>&1 1>&3-)
exec sudo -S -p '' "$0" "$@" <<< "$pass"
exit 1
fi
这使用了鞭尾,如果还没有,可以安装:
sudo apt-get install whiptail
第三种方案
blade19899的答案确实是正确的方法,但是也可以在shebang中调用sudo bash
:
#!/usr/bin/sudo bash
# ...
显而易见的警告是,只有在使用./script
调用脚本时,此方法才有效,而在使用bash script
调用脚本时,此方法将失败。
第四种方案
我在脚本中使用需要以sudo
进行根访问的命令开头-如果用户尚未获得许可,则脚本会在此时提示输入密码。
例
#!/bin/sh
mem=$(free | awk '/Mem:/ {print $4}')
swap=$(free | awk '/Swap:/ {print $3}')
if [ $mem -lt $swap ]; then
echo "ERROR: not enough RAM to write swap back, nothing done" >&2
exit 1
fi
sudo swapoff -a &&
sudo swapon -a
该脚本可以sudo <scriptname>
或<scriptname>
的身份运行。无论哪种情况,它只会询问一次密码。
第五种方案
似乎没有人在这里解决明显的问题。将sudo
放在您随后分发的脚本中会增加不良的用户习惯。 (我假设您正在分发它,因为您提到“从用户的角度”。)
事实是,存在使用应用程序和脚本的准则,该准则类似于银行业的安全性原则:切勿将您的个人信息透露给调用您并声称他们正在“从您的银行打电话”的人由于类似的原因。
申请规则是:
除非出现确定的操作,否则切勿在出现提示时输入密码。这一律适用于具有sudo
访问权限的任何人。
如果您是因为在命令行上运行了sudo
而输入密码,那太好了。如果您是因为运行SSH命令而输入的,则可以。当然,如果您是在登录计算机时输入的,那就太好了。
如果您仅运行外部脚本或可执行文件,并在提示输入密码时温和地输入密码,则您不知道该脚本在做什么。众所周知,它可能以纯文本格式存储在临时文件中,甚至可能无法自动清除。
显然,对于运行一组未知的命令(如root
),存在单独的其他问题,但是我在这里谈论的是维护密码本身的安全性。即使假设该应用程序/脚本不是恶意的,您仍然希望安全地处理您的密码,以防止其他应用程序获取并恶意使用它。
因此,我个人对此的反应是,如果脚本需要root特权,则最好将其放入:
#!/bin/bash
[ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;}
# do privileged stuff, etc.