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'
    技巧似乎不再可读。