让我们假设 bash shell 脚本使用 trap 来执行这样的清理
#!/bin/bash
cleanup() {
sudo umount /mnt
}
trap cleanup EXIT
sudo mount /mnt
#do long running stuff like sleep 3600
上面的脚本(始终取决于中所做的设置/etc/sudoers
)不仅用于用户密码,mount
而且还用于清理umount
。有什么方法可以设置陷阱,例如“已加载 sudo 权限”,这意味着它不需要再次输入用户密码。
理想情况下,不应通过 sudo 运行整个脚本来完成。exec sudo "$0" "$@"
或类似的。只有在可能的情况下,才应该有一种方法可以设置陷阱来运行特权
答案1
trap
您可以执行以下操作,而不是使用 a :
#! /bin/sh -
sudo mount /mnt || exit
{
(
sleep 3600
) 3>&1 >&4 4>&- | sudo sh -c 'cat>/dev/null; umount /mnt'
} 4>&1
该方法sudo sh...
在之后立即启动sudo mount
,但umount
仅在管道关闭时启动,即当其中的子 shellsleep
终止时。
另请注意,您可以看出mount
普通用户可以/mnt
通过/etc/fstab
、user
、或选项进行挂载。有关详细信息,请参阅 mount(8) 和手册页。group
users
owner
fstab(4)
答案2
以下是如何使 umount 命令以 root 身份使用相同的 sudo 凭据运行,即使凭据在命令完成之前超时:
创建一个临时文件,该文件将用作保持挂载点安装的信号,并在清理挂钩中删除该文件。设置一个观察程序脚本,该脚本以 root 身份使用 sudo 运行,并监视该文件的删除,并在删除时进行卸载。
#!/bin/bash
keepmounted=$(mktemp -t keepmounted.$$.XXXXXX)
cleanup() {
rm -f "$keepmounted"
}
trap cleanup EXIT
touch "$keepmounted"
sudo mount /mnt
sudo sh -c "while test -e $keepmounted; do sleep 0.5; done; umount /mnt" &
echo "Doing long running task..."
sleep 3
sudo -k # Reset cached credentials to simulate long enough time
echo "done."
答案3
您可以NOPASSWD
在 中使用修饰符sudoers
,例如
humanityANDpeace ALL = NOPASSWD:/bin/umount /mnt
当然,这将允许您卸载/mnt
任何时间,无论那里安装了什么。但更改为没有其他用途的其他安装点可能是一个简单的解决方法。