我正在尝试从使用常规权限运行的应用程序以 root 身份执行一个进程pkexec
。
当我pkexec
同步调用时一切都很好但是当我使用以下代码异步运行它时:
private void execute_process_async () {
if (permission.allowed ) {
...
Pid child_pid;
var cli = "%s/my_exec".printf (Build.PKGDATADIR);
try {
Process.spawn_async (null,
{ "pkexec", cli,
settings.scrollbar_width.to_string (),
settings.scrollbar_button_radius.to_string (),
settings.active_tab_underline_color
},
Environ.get (),
SpawnFlags.SEARCH_PATH,
null,
out child_pid);
} catch (SpawnError e) {
report_error ("error while executing '%s'. Message: '%s'.".printf (cli, e.message)) ;
}
}
}
我收到一条相当严重的错误信息:
Refusing to render service to dead parents.
你知道发生什么事了吗?
答案1
不允许pkexec
通过 fork 和 exec 在后台运行,然后终止父进程。该进程将成为孤儿进程,属于init
(ppid == 1)。请参阅https://lists.ubuntu.com/archives/foundations-bugs/2012-July/100103.html。
您正在将应用程序的控制权交给另一个用户(通常是 root)。默认方式是以 root 身份从 shell 脚本运行应用程序pkexec
。这样,父级就是 shell,而不是init
。
例如 GParted ( /usr/bin/gparted-pkexec
) 和 GameConqueror ( /usr/bin/gameconqueror
) 就是这样做的,如下所示:
创建一个 shell 脚本如下
/usr/local/bin/foo.sh
:#!/bin/sh pkexec "/usr/sbin/foo" "$@"
赋予上述脚本可执行权限:
chmod +x /usr/local/bin/foo.sh
如果您使用
.desktop
文件,请将Exec
值更改为:Exec=/usr/local/bin/foo.sh
确保您的策略文件中
/usr/share/polkit-1/actions/
有以下条目以允许 GUI:<annotate key="org.freedesktop.policykit.exec.allow_gui">TRUE</annotate>
就是这样!
答案2
看看这个关联它对我有用。
- 它解释了如何安装提供 pkexec 的 policykit-1。
- 解释 gui su 快速权限提升的用法
Bash 别名设置,使用别名运行程序,无需输入
pkexec application-name
相反,它变成别名(应用程序名称):
application-name