答案1
我知道这是一个老问题,但还没有得到解答。评论者说得对,应该使用 pkexec,但就其本身而言,您需要通过添加政策到 polkit-1,或者将某些细节传递给 pkexec。
如果不执行此操作,pkexec nautilus
则会返回错误消息cannot open display:
。
因此,对此问题有两个答案。
单一应用授权
如果您只想授权一个应用程序(例如,Gedit 或 Nautilus),您可以向 polkit-1 添加策略。这是更复杂的方法,但它有一些优点,因此我在这里将其包括进来以保证完整性。
在下面,我使用了文本[app]
,但您应该将其替换为应用程序名称。例如,对于 Nautilus,请将[app]
替换为nautilus
没有方括号。
com.ubuntu.pkexec.[app].policy
在文件夹中创建一个名为的文件/usr/share/polkit-1/actions
,其中包含以下内容。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="com.ubuntu.pkexec.[app]">
<message gettext-domain="[app]">Authentication for [app]</message>
<icon_name>[app]</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/[app]</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>
全部更改五[app]
文件内容中的 实例。<message ...>
部分中的措辞是供人眼阅读的,因此您可以替换[app]
为 (例如)Nautilus
或the file manager
。
答案:信用致 Radu Rădeanu
通用解决方案
适用于任何应用(无论是否 GUI)的通用解决方案是使用 pkexec 通过将两个参数传递给目标应用。同样,根据您的要求,有两种解决方案。
仅从终端
如果您只打算在从终端手动输入此命令时使用它,而不是从脚本输入,请为 pkexec 创建别名。您可以随意命名别名;在此示例中,我使用了相同的名称 pkexec。您可以在初始化脚本中设置它~/.bashrc
。
alias pkexec="pkexec env DISPLAY='${DISPLAY:-}' XAUTHORITY='${XAUTHORITY:-}'"
现在,您可以使用:
pkexec nautilus
从终端或脚本
如果您需要从脚本调用 pkexec,则别名不起作用。这需要不同的方法。
在您的路径中创建一个脚本;我将其命名为pk
并将其放在我的首选个人路径中~/bin
。在脚本中,放置以下两行:
#!/usr/bin/env bash
pkexec env DISPLAY="${DISPLAY:-}" XAUTHORITY="${XAUTHORITY:-}" "${@}"
确保脚本可执行:
chmod +x pk
现在,你可以使用 pk 调用任何应用程序。示例:
pk nautilus
pk gedit
pk apt install --dry-run meld
优点和缺点
每种方法都有其优点和缺点。
如果这是您所需要的,您可以使用策略来微调访问。
有了策略,您就可以添加一条有意义的消息;如果没有策略,您只会得到一条无用的消息“需要经过身份验证才能以超级用户身份运行‘/usr/bin/env’”。
使用策略需要您提前为需要以 root 身份运行的每个应用程序创建一个策略文件。如果您希望精确(有利于安全),这很好,但如果您需要临时访问其他应用程序,则不太好。
使用别名意味着您只能在从终端手动输入时使用它,如果您只需要这样就没问题。使用脚本意味着确保脚本在您的路径上,以便您可以在终端中访问它,并且需要它的脚本也可以访问它。