Java 让脚本检测gnome会话
我有一个Java 让脚本检测gnome会话,java,sudo,environment,gnome,gnome-terminal,Java,Sudo,Environment,Gnome,Gnome Terminal,我有一个makeself脚本,我希望它作为root用户运行;这是一个桌面安装程序 在脚本结束时,最近安装到文件系统的软件尝试在用户空间中启动 使用sudo-u$(logname)/path/to/application(或交替使用)这一方法效果很好,但是缺少来自用户的关键环境变量: GNOME_DESKTOP_SESSION_ID 我需要GNOME\u DESKTOP\u SESSION\u ID,因为子进程属于Java,Java使用这个环境变量来检测进程 然而,尝试使用的尝试失败了 从一些基
makeself
脚本,我希望它作为root用户运行;这是一个桌面安装程序
在脚本结束时,最近安装到文件系统的软件尝试在用户空间中启动
使用sudo-u$(logname)/path/to/application
(或交替使用)这一方法效果很好,但是缺少来自用户的关键环境变量:
GNOME_DESKTOP_SESSION_ID
我需要GNOME\u DESKTOP\u SESSION\u ID
,因为子进程属于Java,Java使用这个环境变量来检测进程
然而,尝试使用的尝试失败了
从一些基本测试来看,当用户登录时,GNOME\u DESKTOP\u SESSION\u ID
似乎不是一个自然的环境变量。例如,如果我CTRL+ALT+F1
到一个终端,env | grep GNOME
不产生任何结果,而XTerm
和GNOME终端
都产生GNOME\u DESKTOP\u SESSION\u ID
如何从安装程序脚本中获取此GNOME\u DESKTOP\u SESSION\u ID
变量,而无需用户向sudo
命令传递-E
等参数
注意,虽然这是Linux的主要外观,但我也不喜欢硬编码,出于支持、寿命和可伸缩性的原因,我更喜欢继续使用Oracle的检测技术
更新:在Ubuntu中,GNOME\u DESKTOP\u SESSION\u ID
位于/usr/share/upstart/sessions/xsession init.conf
initctl set-env --global GNOME_DESKTOP_SESSION_ID=this-is-deprecated
这导致使用
initctl get env
来检索它。不幸的是,这在新的sudo
shell中没有帮助,也没有任何(乐观的)尝试dbus启动
您需要使用以下内容在/etc/sudoers.d上创建一个新文件:
Defaults env_keep+=GNOME_DESKTOP_SESSION_ID
但是,有一个问题,如果你已经在sudo里面,它将不会被再次阅读
因此,完整的解决方案是在脚本中使用sudo创建此文件,然后在另一个sudo中执行命令:
#!/bin/bash
# ignore sudo
if [[ -z $SUDO_USER ]]; then
#save current dir
DIR="$(pwd)"
#generate random string (file name compatible)
NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
#create env_keep file
sudo -i -- <<EOF0
echo "Defaults env_keep+=GNOME_DESKTOP_SESSION_ID" > /etc/sudoers.d/"$NEW_UUID"_keep_java_laf
EOF0
sudo -u YOUR_USER -i -- <<EOF
#go to original directory
cd "$DIR"
#execute your java command
java YOUR_COMMAND
EOF
#clean file
sudo rm -f /etc/sudoers.d/"$NEW_UUID"_keep_java_laf
else
echo "sudo not allowed!";exit 1;
fi
#/bin/bash
#忽略sudo
如果[-z$SUDO_USER]];然后
#保存当前目录
DIR=“$(pwd)”
#生成随机字符串(文件名兼容)
新UUID=$(cat/dev/urandom-tr-dc'a-zA-Z0-9'|折叠-w 32 |头部-n 1)
#创建环境保存文件
sudo-i--事实证明这是一个两步的过程
从/proc/$pid/environ
然后export UPSTART\u SESSION
并调用initctl--user get env GNOME\u DESKTOP\u SESSION\u ID
为了使它对其他变量更具可伸缩性,我将其包装到一个bash助手函数中。此函数还应帮助获取其他用户环境变量注意,如果变量的值在名称中有空格,它将不起作用。
在下面的示例中,回答问题只需要UPSTART\u SESSION
和GNOME\u DESKTOP\u SESSION\u ID
调用sudo\u env
后,对sudo-u…
的下一次调用必须更改为sudo-E-u…
。-E
将导入新导出的变量以供子进程使用
# Provide user environmental variables to the sudo environment
function sudo_env() {
userid="$(logname 2>/dev/null || echo $SUDO_USER)"
pid=$(ps aux |grep "^$userid" |grep "dbus-daemon" | grep "unix:" |awk '{print $2}')
# Replace null delimiters with newline for grep
envt=$(cat "/proc/$pid/environ" |tr '\0' '\n')
# List of environmental variables to use; adjust as needed
# UPSTART_SESSION must come before GNOME_DESKTOP_SESSION_ID
exports=( "UPSTART_SESSION" "DISPLAY" "DBUS_SESSION_BUS_ADDRESS" "XDG_CURRENT_DESKTOP" "GNOME_DESKTOP_SESSION_ID" )
for i in "${exports[@]}"; do
# Re-set the variable within this session by name
# Careful, this technique won't yet work with spaces
if echo "$envt" | grep "^$i=" > /dev/null 2>&1; then
eval "$(echo "$envt" | grep "^$i=")" > /dev/null 2>&1
export $i > /dev/null 2>&1
elif initctl --user get-env $i > /dev/null 2>&1; then
eval "$i=$(initctl --user get-env $i)" > /dev/null 2>&1
export $i > /dev/null 2>&1
fi
echo "$i=${!i}"
done
}
谢谢这与sudo-u-foo
结合起来如何工作?逻辑有帮助,但不能解决问题。除非我注释掉rm-f
行,硬编码文件名并再次运行安装程序,否则建议的修复似乎没有帮助。这是一个已具有root权限的安装程序,其本身已在sudo
调用中。顺便说一句。。。根据sudoers自述文件
,您应该在调用echo之前使用umask 0337
,但设置似乎太晚了。安装程序已经用sudo
启动,环境变量丢失了(我假设)。我想特别提到@dyorgio在这方面的帮助。他在另一个帮助论坛上向我提供了/proc/$pid/environ
逻辑,这是上述解决方案的50%。谢谢@dyorgio,仅供参考,GNOME\u DESKTOP\u SESSION\u ID
在Ubuntu 18.04上使用cat”/proc/$pid/environ“| tr'\0'\n'
技巧似乎不再可读。