Ind*_*ial 7 bash shell ubuntu sudo
我做了一个简单的bash脚本,需要在整个脚本中保持它的超级用户权限.不幸的是,但是可以理解的是,脚本sudo在sleep发生时会丢失其权限.对我不好:
sudo echo "I am sudo!" # Asks for passwords
sleep(60)
sudo echo "I am sudo!" # Need to enter password again.
Run Code Online (Sandbox Code Playgroud)
我想过sleep用一个让sudo保持活着的while循环来替换它,但是我很确定有更好的选择可以使sudo-permissions在整个脚本中保持不变?
谢谢
seh*_*ehe 10
sudo的灵活性被广泛低估.这导致非常糟糕的做法(如sudo su -佳能球手术方法).
一个更好的方法是特定地允许您打算允许的命令而不使用密码:
phill = NOPASSWD: /bin/ls, /usr/bin/lprm
Run Code Online (Sandbox Code Playgroud)
您可以选择对作为特定管理员用户运行的特定主机的特定用户执行此操作.您甚至可以阻止用户将shell转义作为参数传递.您可以使sudo阻止启动的程序动态执行其他应用程序等.您将需要阅读sudoers的手册页(并确保阅读编辑此特殊文件的过程!).
这里有一小部分东西,(从这里):
User_Alias OPERATORS = joe, mike, jude
Runas_Alias OP = root, operator
Host_Alias OFNET = 10.1.2.0/255.255.255.0
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
OPERATORS ALL=ALL
#The users in the OPERATORS group can run any command from any terminal.
linus ALL=(OP) ALL
# The user linus can run any command from any terminal as any user in the OP group (root or operator).
user2 OFNET=(ALL) ALL
# user user2 may run any command from any machine in the OFNET network, as any user.
user3 ALL= PRINTING
# user user3 may run lpc and lprm from any machine.
go2linux ALL=(ALL) ALL
# user go2linux may run any command from any machine acting as any user. (like Ubuntu)
If you want not to be asked for a password use this form
go2linux ALL=(ALL) ALL NO PASSWD: ALL
Run Code Online (Sandbox Code Playgroud)
严格在脚本中工作(而不是编辑 sudoers 文件或通过 调用脚本sudo ./script.sh),这是我认为最干净的方法。
startsudo() {
sudo -v
( while true; do sudo -v; sleep 50; done; ) &
SUDO_PID="$!"
trap stopsudo SIGINT SIGTERM
}
stopsudo() {
kill "$SUDO_PID"
trap - SIGINT SIGTERM
sudo -k
}
Run Code Online (Sandbox Code Playgroud)
基本上,这定义了一对用于启用和禁用 sudo 模式的函数。startsudo在运行使用 sudo 的代码之前调用使用 sudo 进行身份验证,分叉后台 sudo 刷新循环,保存循环的 PID,并设置信号陷阱以在按下 Ctrl+C 时停止 sudo 模式。调用会stopsudo终止循环,清除信号陷阱,并使之前使用 sudo 的身份验证无效。
将这些函数复制到脚本中后,像这样使用它们。
startsudo
echo "Sudo mode is active."
# whatever you want to do with sudo
stopsudo
Run Code Online (Sandbox Code Playgroud)
我要感谢 @karl 简单地内联 sudo-refreshing 循环和 @sehe 指出如果循环没有被正常终止,应该使用信号陷阱来终止它。这两个想法都改进了我的 btrfs 备份脚本,它使用 sudo 刷新循环来避免在子卷的备份时间超过 sudo 超时后重新提示用户。
您可以通过添加到/ etc/sudoers来调整此超时
Defaults timestamp_timeout=#Number of minutes
Run Code Online (Sandbox Code Playgroud)
但它更容易运行
sudo ./worker.sh
Run Code Online (Sandbox Code Playgroud)
小智 5
这是一个解决方法:
sudo echo "I am sudo!" # Asks for passwords
( while true; do sudo -v; sleep 40; done ) & # update the user's timestamp
sudoPID=$!
# ...
sleep(60)
sudo echo "I am sudo!" # Need to enter password again.
kill -TERM $sudoPID
sudo -k # invalidate the user's timestamp at end of script (does not require a password)
Run Code Online (Sandbox Code Playgroud)