编辑

编辑

我有一个来自这个线程的问题如何通过在 sudoers 中输入路径双击来运行 bash 脚本?。由于向我解释了sudo向文件授予权限是不安全的script.sh,因此我决定找到一种双击文件script.sh而不sudo向文件本身授予权限的方法。并确保其安全

我正在使用 Debian 12 和 KDE Plasma 桌面环境。要运行命令sudo sh /path/to/script.sh,您需要转到终端,键入sudo sh /path/to/script.sh,然后输入密码。我想要一个可以在用户界面中双击的文件,然后运行该文件sudo sh /path/to/script.sh,因此双击后我需要做的就是输入密码。

脚本内有一些命令只能与 一起使用sudo,例如ip tuntap add dev,, 或route add。我怎样才能做到这一点?

谢谢。

答案1

编辑

由于您编辑了评论以提供更多信息,我现在可以给您一个完整的答案。我向运行 KDE Plasma 的朋友进行了验证,他说默认行为是双击桌面上的脚本将启动它,前提是设置了可执行位。它不会在终端中启动它,因此脚本必须创建自己的终端。考虑到这一点,以下是说明:

  1. 将 shebang 添加到您的脚本中

将该行添加#!/bin/sh到脚本的最开头。这会告诉您系统使用哪个 shell 来执行您的文件。

  1. 使文件可执行

右键单击该文件permissions,然后勾选下面的复选框executable。或者,运行chmod +x /path/to/script.sh.

  1. sudo在脚本内部为每个命令(需要它)添加前缀

  2. 确保脚本在终端中打开

您可以通过在脚本开头(但在 shebang 之后)添加以下代码片段来完成此操作:

test "$IN_TERM" || {
    export IN_TERM=1
    konsole --hold -e "$0"
    exit 0
} && true

这使用 Konsole,KDE 的默认终端。该--hold标志确保脚本完成后终端保持打开状态,以便您可以验证它是否正确运行。

就是这样,一切都应该正常!

例子

为了大致了解一切应该是什么样子,这里有一个我的系统上的类似脚本。它没有改变网络设置,而是改变了我的笔记本电脑的充电行为,但总体思路是相似的。

#!/bin/sh

set -x  # Print all commands before running them
set -e  # Exit on first error

test "$IN_TERM" || {
    export IN_TERM=1
    alacritty --hold -e "$0"  # I use alacritty as my terminal.
    exit 0
} && true

sudo -v  # Ask for password, but don't run any command

# Subsequent invocations of `sudo` won't ask for password
sudo tpacpi-bat -s ST 1 0
sudo tpacpi-bat -s SP 1 0

echo 'Done!'

安全

在评论中,您提到您担心放入sudo脚本本身。我不是安全研究人员,但我向您保证,这是完全正确且安全的。sudo仍会提示用户输入密码。系统上的任何其他用户或以您的用户权限运行的恶意程序将无法以任何方式利用您的脚本。放入sudo脚本可能会令人不悦,但出于与安全无关的原因(例如,sudo如果您打算将此脚本分发给其他人,则放入脚本可能会出现问题,因为并非每个人都sudo安装了)。

旧答案

正如评论所指出的,我们无法真正帮助您,因为您没有告诉我们您正在使用什么发行版/桌面环境。

不过,我可以给你一些建议。

移动sudo脚本内部

我认为在这种情况下,最好将sudo调用移至脚本本身。您可以通过在脚本开头添加类似的内容来完成此操作:

test "$(id -u)" -eq 0 || {
    sudo sh "$0"
    exit 0
}

另一种选择是创建第二个脚本来启动第一个脚本sudo。第三种选择是简单地在脚本中的任何 root-only 命令前加上sudo.它只会询问密码一次。

设置可执行位

在终端中,运行chmod +x /path/to/script.sh.这使得该文件可执行。您可以通过使用/path/to/script.sh而不是启动脚本来测试它是否有效sh /path/to/script.sh。在某些桌面环境中,这也可能使脚本可以通过 GUI 双击运行。

设置正确的shebang

确保您的脚本以#!/bin/sh(或#!/bin/bash(或#!/usr/bin/env bash) 开头,如果您的脚本使用仅限 bash 的功能)

在发行版的设置应用程序中深入研究

由于安全原因,双击启动脚本可能会被禁用。尝试在文件管理器或桌面环境设置中查找此选项。这里

创建一个.desktop文件。

如果上述操作失败,您可以创建一个包含myscript.desktop以下内容的文件(并编辑TypeCommentExec字段):

[Desktop Entry]
Version=1.0
Type=Application
Name=your_human_friendly_name
Comment=your_human_friendly_comment
Exec=/path/to/script.sh
Terminal=false
StartupNotify=false
Categories=Application;

您现在可以双击该文件来运行脚本。请注意,您需要将其移至sudo脚本中。如果您需要在终端内启动脚本,请更改该Terminal字段。请注意,您的脚本需要设置可执行位才能使此方法发挥作用。

文件的另一个好处.desktop是,如果您将其放入/usr/share/applications~/.local/share/applications,也可以通过应用程序启动器访问它。

另外,有一个工具可以gendesk自动.dekstop为您创建文件,但手动编写文件也可以。

使用gksudo

如果您确实弄清楚如何实现您想要的行为,但如果您的桌面环境在没有终端的情况下启动脚本,则可能仍然无法运行脚本,因为您无法输入sudo.考虑安装该软件包gksudo(可能有不同的名称,具体取决于发行版)并使用它而不是sudo.它的工作方式相同,但创建一个 GUI 密码输入框而不是使用终端

让脚本启动自己的终端

如果您出于交互以外的原因需要在终端中启动脚本sudo(例如,向用户显示输出),您可以将其放在脚本的开头(但在 shebang 之后),以确保它始终在终端中启动终端:


test "$IN_TERM" || {
    export IN_TERM=1
    alacritty --hold -e "$0"
    exit 0
} && true

请注意,上面的代码片段使用的alacritty是我的首选终端。将其更改为您使用的任何终端。另请注意--hold-e标志,它们也是特定于 alacritty 的。-e实际上-c在大多数其他终端上。

使用rofi

这并不能回答您的问题,但我认为您可能会发现它很有用。如果您发现自己有很多不同的脚本需要能够快速启动,请考虑rofi.它将允许您拥有所有脚本的可搜索菜单,随时可以启动。要以这种方式使用 rofi,您首先需要创建一个rofi_launch.sh如下所示的脚本(我们称之为):

#!/bin/bash

if [ -z "$1" ]; then
    ls /path/to/where/you/store/your/scripts
else
    FILE="/path/to/where/you/store/your/scripts/$1"
    killall rofi
    "$FILE" & disown
fi

然后,启动 rofi rofi -show RUN:/path/to/rofi_launch.sh(您可以将其绑定到桌面环境设置中的键盘快捷键),您应该有一个菜单,您可以从中启动任何脚本。

答案2

我只是来晚了一点,伦泽夫已经为你提供了一个很好的答案。然而,为了完整起见,我觉得有必要提一下pkexec。用法非常简单pkexec /path/to/script.sh(假设脚本已设置其可执行位)。此外,这种方法与文件非常匹配.desktop

pkexec(或者实际上,polkit,它所属的机制)是升级权限的另一种标准方法,并且往往与图形桌面更有效地配对。如果您使用过像 Gparted 这样需要 root 访问权限的工具,它通常会通过弹出图形密码提示来实现这一点 — 这就是 polkit 的作用。

具体的弹出窗口实际上是由您的桌面环境提供的,因此窗口管理器用户可能需要显式安装一个。既然您提到使用 Plasma,那么您已经内置了一个。

相关内容