如何防止 bash EXIT 陷阱中出现 sudo 密码提示?

如何防止 bash EXIT 陷阱中出现 sudo 密码提示?

让我们假设 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/fstabuser、或选项进行挂载。有关详细信息,请参阅 mount(8) 和手册页。groupusersownerfstab(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 任何时间,无论那里安装了什么。但更改为没有其他用途的其他安装点可能是一个简单的解决方法。

相关内容