Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash Shell脚本-随时间丢失Sudo权限_Bash_Shell_Ubuntu_Sudo - Fatal编程技术网

Bash Shell脚本-随时间丢失Sudo权限

Bash Shell脚本-随时间丢失Sudo权限,bash,shell,ubuntu,sudo,Bash,Shell,Ubuntu,Sudo,我制作了一个简单的bash脚本,需要在整个脚本中保持它的超级用户权限。不幸的是,当睡眠发生时,脚本会失去其sudo-eleveted权限,这是可以理解的。对我不好: sudo echo "I am sudo!" # Asks for passwords sleep(60) sudo echo "I am sudo!" # Need to enter password again. 我想用一个while循环来代替sleep,使sudo保持活动状态,但我很确定有更好的选项可以让sudo-权限在整个

我制作了一个简单的bash脚本,需要在整个脚本中保持它的超级用户权限。不幸的是,当
睡眠
发生时,脚本会失去其
sudo
-eleveted权限,这是可以理解的。对我不好:

sudo echo "I am sudo!" # Asks for passwords
sleep(60)
sudo echo "I am sudo!" # Need to enter password again.
我想用一个while循环来代替
sleep
,使sudo保持活动状态,但我很确定有更好的选项可以让
sudo
-权限在整个脚本中保持不变


谢谢

您可以通过添加到/etc/sudoers来调整此超时

Defaults timestamp_timeout=#Number of minutes
但它更容易运行

sudo ./worker.sh
这里有一个解决方法:

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)

一次性获得根用户权限:

sudo su -
# What I need to do with root 

人们普遍低估了sudo的灵活性。这导致了非常糟糕的实践(如
sudo su-
canon ball手术方法)

更好的方法是在不使用密码的情况下具体允许您想要允许的命令

phill = NOPASSWD: /bin/ls, /usr/bin/lprm

您可以选择对作为特定管理员用户运行的特定主机中的特定用户执行此操作。您甚至可以阻止用户将shell转义作为参数传递。您可以使sudo阻止启动的程序动态执行其他应用程序等

这里有一点东西的味道,():

这是我的方式:

#!/bin/sh
echo "Working..."
# add you pass
echo "yourpass" >> file.pass ;sleep 5 
# Check if root
if [ `cat file.pass | sudo -S su root -c whoami` != "root" ]; then
echo "Not running as root. Exiting..."
sleep 2
echo "Cleaning..."
sleep 1
srm file.pass
echo "Cleaned"
exit 0
else
echo "Running as root. Good"
sleep 2
# and run any sudo with
cat file.pass | sudo -S su root -c ls #<any command>
fi

sleep 5
echo `cat file.pass | sudo -S su root -c whoami` "say bay bay"
# if pass no longer need
srm file.pass
echo "End session :)"
exit 0
#/垃圾箱/垃圾箱
回声“工作…”
#添加你的通行证
echo“yourpass”>>file.pass;睡眠5
#检查是否为根
如果[`cat file.pass | sudo-S su root-c whoami`!=“root”];然后
echo“不是以root身份运行。正在退出…”
睡眠2
回声“清洁…”
睡眠1
srm file.pass
echo“已清理”
出口0
其他的
echo“以root身份运行,很好”
睡眠2
#和你一起玩sudo
cat file.pass | sudo-S su root-c ls#
fi
睡眠5
echo`cat file.pass | sudo-S su root-c whoami`“说bay”
#如果通行证不再需要
srm file.pass
echo“结束会话:)”
出口0

严格在脚本中工作(不编辑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
}
基本上,这定义了一对用于启用和禁用sudo模式的函数。在运行sudo之前调用
startsudo
,使用代码对sudo进行身份验证,分叉后台sudo刷新循环,保存循环的PID,并设置信号陷阱以在按下Ctrl+C时停止sudo模式。调用
stopsudo
将终止循环,清除信号陷阱,并使sudo的早期身份验证无效

将这些函数复制到脚本中后,请像这样使用它们

startsudo
echo "Sudo mode is active."
# whatever you want to do with sudo
stopsudo

我要感谢@karl内联sudo刷新循环的简单性,@sehe指出,如果循环不能正常终止,应该使用信号陷阱终止循环。这两种想法都得到了改进,它使用了sudo刷新循环,以避免在子卷的备份时间超过sudo的超时时间后重新提示用户。

为什么不让用户运行它
sudo
?如果你打算这样做,至少要确保kill和
sudo-k
在脚本中注册为信号陷阱。这就要求有很大的安全漏洞。(使用Ctrl-C中止脚本,sudo会无限期保持活动状态)这看起来像是一个有效的答案,但将用户密码保存到文件中似乎相当不安全。另外,
srm
命令的作用是什么?我的Linux发行版没有它。
startsudo
echo "Sudo mode is active."
# whatever you want to do with sudo
stopsudo