我如何在 bash 脚本的开头请求提升的权限并让它结束?

How can I request elevated permissions in a bash script's begin and let it go at the end?

我有一个脚本 (myscript.sh),其中 运行 有一些命令需要 提升权限 (即需要 运行 和 sudo).

脚本比较复杂,但演示如下:

#!/bin/bash
echo "hello"
command1_which_needs_sudo
echo "hello2"
command2_which_needs_sudo
echo "hello3"
...

如果我运行它是一个没有所需权限的普通用户:

$ ./myscript.sh
hello
must be super-user to perform this action

但是,如果我 运行 它具有正确的权限,它将正常工作:

$ sudo ./myscript.sh
hello
hello2
hello3

我能否在没有 sudo 的情况下以某种方式实现 运行 myscript.sh,并使脚本请求提升的权限 仅在开始时 一次(并在完成后将其传回)?

所以很明显,sudo command1_which_needs_sudo不会好,因为command2也需要权限。

如果我不想创建另一个文件,并且由于脚本的复杂性,我也不想使用 heredoc 语法来执行此操作,我该如何执行此操作?

如果您主要关心的是代码的清晰度,那么使用包装函数会有很多好处。

# call any named bash function under sudo with arbitrary arguments
run_escalated_function() {
  local function_name args_q
  function_name=; shift || return
  printf -v args_q '%q ' "$@"
  sudo bash -c "$(declare -f "$function_name"); $function_name $args_q"
}

privileged_bits() {
  command1_which_needs_sudo
  echo "hello2"
  command2_which_needs_sudo
}

echo "hello"
run_escalated_function privileged_bits
echo "hello3"

如果你想 运行 具有 root 权限的脚本而不必在终端中键入 sudo 也不必多次键入密码,那么你可以使用:

#!/bin/bash

if [ "$EUID" -ne 0 ]
then
    exec sudo -s "[=10=]" "$@"
fi

echo "hello"
command1_which_needs_sudo
echo "hello2"
command2_which_needs_sudo
echo "hello3"
# ...

sudo -k

更新:

如果您的目标是使用 sudo 权限执行脚本的一部分,那么使用此处引用的文档 可能是最简单的解决方案;不会有任何语法问题,因为当前 shell 不会在其中展开任何内容。

#!/bin/bash

echo "hello"

sudo -s var="hello2" <<'END_OF_SUDO'

command1_which_needs_sudo
echo "$var"
command2_which_needs_sudo

END_OF_SUDO
sudo -k

echo "hello3"
#...

备注: 请注意,您可以通过在 sudo 命令中设置 varname=value 来在 here-document 脚本中使用外部值。