我想消除用户在运行sudo
命令的 bash 脚本中多次输入密码的需要。我如何循环输入密码直到sudo echo
返回 0,然后将密码存储在变量中以供脚本范围内使用?
答案1
当然,可以消除对特定命令甚至整个脚本输入 sudo 密码的需要。
您建议的将密码存储在脚本中的局部变量中的方法是相当不明智的。任何具有读取权限的人都/proc/<pid>/environ
可以读取局部变量。任何获得脚本读取权限的人,只要拥有硬编码的凭据,都可以使用这些凭据将权限提升为 root 并拥有您的系统。在单用户系统上,这仍然是不明智的,因为针对 Linux 用户的远程攻击越来越多。
如果没有你的脚本的具体细节,我只能建议你阅读 Ubuntu 社区 Wiki -Sudoers。然后通过运行修改您的 sudoers 文件sudo visudo
,将特定命令添加到文件中。
可能您应该添加两行,一行用于添加命令别名,第二行用于授权用户运行这些命令。
允许特定用户(即 bob)无需密码即可运行选定的关机命令的示例。
Cmnd_Alias SHUTDOWN_CMDS = /sbin/poweroff, /sbin/halt, /sbin/reboot
bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS
以下脚本是如何在脚本中包含安装、卸载或编辑示例行的功能的示例/etc/sudoers
。
#!/bin/bash
#Set Script Name variable
SCRIPT=`basename ${BASH_SOURCE[0]}`
#Initialize variables to default values.
OPT_i=i
OPT_u=u
OPT_e=e
OPT_m=m
#Set fonts for Help.
NORM=`tput sgr0`
BOLD=`tput bold`
REV=`tput smso`
#Help function
function HELP {
echo -e \\n"Help documentation for ${BOLD}${SCRIPT}.${NORM}"\\n
echo -e "${REV}Basic usage:${NORM} ${BOLD}$SCRIPT file.ext${NORM}"\\n
echo "Command line switches are optional. The following switches are recognized."
echo "${REV}-1${NORM} --Installs lines in /etc/sudoers to allow script to be run without entering password multiple times."
echo "${REV}-u${NORM} --Unistalls lines in /etc/sudoers."
echo "${REV}-e${NORM} --Launces visudo to edit /etc/sudoers."
echo "${REV}-m${NORM} --Launces main."
echo -e "${REV}-h${NORM} --Displays this help message. No further functions are performed."\\n
exit 1
}
#Install function
function INSTALL {
echo "launching Install"
echo -e '#script_append'\\n'Cmnd_Alias SHUTDOWN_CMDS = /sbin/poweroff, /sbin/halt, /sbin/reboot'\\n'bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS' | sudo EDITOR='tee -a' visudo
}
#Unnstall function
function UNINSTALL {
echo "launching uninstall"
bash -c 'printf ",g/^#script_append$/d\nw\nq\n" | sudo EDITOR='ed' visudo'
bash -c 'printf ",g/^Cmnd_Alias.*reboot$/d\nw\nq\n" | sudo EDITOR='ed' visudo'
bash -c 'printf ",g/^bob ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS$/d\nw\nq\n" | sudo EDITOR='ed' visudo'
}
#Main function
function MAIN {
echo "launching editor via main"
sudo visudo
}
#Check the number of arguments. If none are passed, print help and exit.
NUMARGS=$#
echo -e \\n"Number of arguments: $NUMARGS"
if [ $NUMARGS -eq 0 ]; then
HELP
fi
### Start getopts code ###
#Parse command line flags
#If an option should be followed by an argument, it should be followed by a ":".
#Notice there is no ":" after "h". The leading ":" suppresses error messages from
#getopts. This is required to get my unrecognized option code to work.
while getopts ":iuemh" FLAG; do
case "${FLAG}" in
i) #set option "i"
OPT_i=${OPTARG}
echo "-i used: $OPTARG"
if sudo grep -q '#script_append' /etc/sudoers
then
echo "Sudoers apperes to have already been installed"
exit
else
INSTALL
fi
;;
u) #set option "u"
OPT_u=$OPTARG
echo "-u used: $OPTARG"
UNINSTALL
;;
e) #set option "e"
OPT_e=$OPTARG
echo "-e used: $OPTARG"
sudo visudo
;;
m) #set option "m"
OPT_m=$OPTARG
echo "-m used: $OPTARG"
MAIN
;;
h) #show help
HELP
;;
\?) #unrecognized option - show help
echo -e \\n"Option -${BOLD}$OPTARG${NORM} not allowed."
HELP
#If you just want to display a simple error message instead of the full
#help, remove the 2 lines above and uncomment the 2 lines below.
#echo -e "Use ${BOLD}$SCRIPT -h${NORM} to see the help documentation."\\n
#exit 2
;;
esac
done
shift $((OPTIND-1)) #This tells getopts to move on to the next argument.
### End getopts code ###
答案2
我目前似乎有效的方法如下:
read_sudo_pwd() {
read -s -p "[sudo] password for $USER: " sudo_pwd
until (echo $sudo_pwd | sudo -S echo '' 2>/dev/null)
do
echo -e '\nSorry, try again.'
read -s -p "[sudo] password for $USER: " sudo_pwd
done
}
read_sudo_pwd
echo $sudo_pwd | sudo -S echo 'Hello'
echo $sudo_pwd | sudo -S echo 'World'