如何让 sudo 在密码提示中显示命令?

如何让 sudo 在密码提示中显示命令?

是否可以让 sudo 提示符也显示该命令?

如果您是调用者,那么简单[SUDO] password就很好了。但您经常运行脚本并想仔细检查您同意的内容。我已经将超时设置为零,因此每次都必须确认。

我很想有类似的东西

[SUDO] PWD: /home/user/
[SUDO] CMD: /bin/ls -la *.c
[SUDO] password: _

答案1

关于*.c

首先,制作sudo(或任何支持装置)打印会相当棘手/bin/ls -la *.c,因为当你运行

sudo /bin/ls -la *.c

在 shell 中,它是*.c在启动之前展开的 shell sudosudo获取结果扩张,并且没有办法知道它*.c曾经存在过。

我想魔法别名并且 shell 历史可以做一些事情,但是:

  • 您的关注点sudo在于脚本。脚本的解释器可能是一个不支持历史记录的 shell;即使它支持,在解释脚本时也可能不会这样做;即使它支持,也可能不会默认使用别名。
  • 如果我是你,我会想看到实际的命令到达sudo,例如/bin/ls -la bar.c baz.c foo.c。一个更好的例子是想象脚本调用sudo "$tool" "$arg1" "$arg2";你想看到这个吗?或者扩展的实际的命令?

现在我假设你不一定需要看到*.c,你接受看到任何*.c扩展到的东西。


包装器

您可以构建一个自定义程序sudo来打印您想要的内容并调用真实的sudo。一个相对简单的包装器脚本:

#!/bin/bash
printf '[SUDO] PWD: %s\n' "$PWD" >/dev/tty
printf '[SUDO] CMD: ' >/dev/tty
printf '%s ' sudo "${@@Q}" >/dev/tty
printf '\n' >/dev/tty
exec /usr/bin/sudo "$@"

如果您将脚本命名为sudo,使其可执行,并将其放置在您的$PATHbefore目录中/usr/bin(注意,我假设您的实际sudo/usr/bin/sudo,包装器也是如此),那么每当您调用 时sudo,您都会调用包装器。它将(无条件地)在执行实际 之前打印您想要的信息sudo

笔记:

  • 为单个用户设置这个很容易,即不影响其他用户:将包装器放在私有bin目录中,$PATH并进行相应修改。可以为所有 sudoers 设置这个(但我不会详细说明)。

  • 包装器打印到/dev/tty。这是个好主意(想象一下sudo foo >result 2>log,你不想把result或弄乱log)。你的 realsudo也很可能将其提示打印到 tty。

  • 包装器打印的内容类似于[SUDO] CMD: sudo ls …而不是[SUDO] CMD: ls …您想要的。这是设计使然。想象一下命令是sudo -E ls …[SUDO] CMD: -E ls …看起来很奇怪。解析参数只是为了-E在输出中省略是徒劳的;甚至有害的,你不想知道-E被使用了吗?[SUDO] CMD: sudo -E ls …没问题。

  • 解释器是bash,而不是sh,因为我选择使用@Q来打印引用的参数以避免歧义。或者它可能是printf '%q ' sudo "$@" >/dev/tty。这两个变体可能会给出不同的(但等效的)输出,因此请选择您更喜欢的那个。

  • 脚本可能会$PATH自行更改;或者它可以sudo通过其完整路径调用真实路径。因此它可能会绕过包装器。

  • realsudo足够智能,可以等待另一个sudo使用同一终端的用户。换句话说:两个sudoinsudo foo | sudo bar不会同时要求您输入密码。我们的包装器没有那么智能,两个并行启动的包装器可以并行打印。

包装器并不是一个完美的解决方案。


聚丙烯酰胺

如果您的sudo用途聚丙烯酰胺,可以在询问您的密码之前让它执行一个脚本。

在尝试做任何事情之前,请先读到最后。

注意:本节中我们要做的几乎每件事都需要sudo一个提升权限的 shell ( sudo -i)。您应该启动至少一个提升权限的 shell 并保持其运行,直到完成所有更改后您(作为普通用户)确认您的sudo计算机仍然正常工作。如果您(我们)以某种方式设法破坏了您的计算机,shell 将会成为您的救星sudo

将以下代码另存为/usr/local/bin/sudo_pam_script并使文件可执行。该文件应属于root:root并且其模式应为rwxr-xr-x。这是代码:

#!/bin/bash
printf '[SUDO] PWD: %s\n' "$PWD"
printf '[SUDO] CMD: '
</proc/"$PPID"/cmdline mapfile -d '' arg
printf '%q ' "${arg[@]}"
exit 0

编辑/etc/pam.d/sudo并在所有未注释的行之前添加以下行:

auth    optional    pam_exec.so stdout /usr/local/bin/sudo_pam_script

从现在起,sudo如果脚本要求输入密码,您将运行该脚本。但如果不要求输入密码,它就不会执行此操作。

笔记:

  • 此解决方案是全球性的,它影响所有 sudoers,他们无法轻易选择退出。

  • 我不太了解你的操作系统。你标记了,所以/proc可能存在(但一般来说不必存在)。您sudo可能会或可能不会使用 PAM,或者其配置可能会产生干扰。我在 Kubuntu 中测试了该解决方案。

  • >/dev/tty不是必需的。sudo它本身应该重定向(或者说中继)脚本的输出。

  • 您可以printf '%q ' "${arg[@]}"使用printf '%s ' "${arg[@]@Q}"。尝试两者并选择其中一个。

  • 就 而言,此解决方案比包装器更好sudo foo | sudo bar。但您不会将整个管道视为一个命令,因为每个命令sudo只知道自己的部分。

  • 在我的 Kubuntu 中,该解决方案不适用于sudo -i。有一个单独的文件/etc/pam.d/sudo-i与此案例相关。

相关内容