2016-11-15 3 views
1

루트로 실행될 것으로 예상되는 makeself 스크립트가 있습니다. 데스크톱 설치 프로그램입니다.그놈 세션 감지 스크립트가 있습니다.

스크립트가 끝나면 최근에 파일 시스템에 설치된 소프트웨어가 사용자 공간에서 실행을 시도합니다.

잘 (교대 또는 sudo -u $SUDO_USER ... in Ubuntu 16.04) sudo -u $(logname) /path/to/application 사용자로부터 그러나 중요한 환경 변수를 사용하여 작동이 누락되었습니다 : 자식 프로세스가 자바에 속하고 자바는 검출이 환경 변수를 사용하기 때문에

GNOME_DESKTOP_SESSION_ID 

내가 GNOME_DESKTOP_SESSION_ID 필요 GtkLookAndFeel.

그러나 sudo -i을 사용하려는 시도가 실패했습니다. 몇 가지 기본적인 테스트에서

GNOME_DESKTOP_SESSION_ID 내가 CTRL+ALT+F1 터미널에있는 경우이 사용자 로그. 예를 들어, env |grep GNOME 모두가 GNOME_DESKTOP_SESSION_ID를 얻을 XTermgnome-terminal 반면 아무 것도 얻을 수 없을 때 자연 환경 변수로 표시되지 않습니다.

sudo 명령에 -E 매개 변수와 같은 값을 전달하지 않아도 설치 스크립트에서이 GNOME_DESKTOP_SESSION_ID 변수를 보유하려면 어떻게해야합니까?

GtkLookAndFeel이 Linux의 기본 모양과 느낌이지만 export JAVA_OPTS을 하드 코딩하지 않는 것이 좋습니다. 지원, 수명 및 확장 성의 이유로 오라클의 탐지 기술로 대체하는 것을 선호합니다.

업데이트 : 우분투에서, 그것을 검색하는 initctl get-env를 사용하여 리드 /usr/share/upstart/sessions/xsession-init.conf

initctl set-env --global GNOME_DESKTOP_SESSION_ID=this-is-deprecated 

에서 GNOME_DESKTOP_SESSION_ID 살고있다. 불행하게도 이것은 새로운 sudo 쉘에서 도움이되지 않으며 dbus-launch에서 (낙관적 인) 시도도하지 않습니다.

Defaults env_keep+=GNOME_DESKTOP_SESSION_ID 

을하지만 당신은 이미 내부 sudo는이 경우, 문제는 다시 읽지 않을 것이다,이 :

답변

1

그것은 ...

이 과정은 두 단계로 이루어집니다 끈다는
  1. 그런 다음 /proc/$pid/environ
  2. export UPSTART_SESSION에서 사용자의 UPSTART_SESSION 환경 변수를 읽고 전화 initctl --user get-env GNOME_DESKTOP_SESSION_ID

이 변수를 다른 변수에 맞게 확장하려면 bash 도우미 함수로 래핑했습니다.이 함수는 다른 사용자 환경 변수도 가져 오는 것을 도와야합니다. 주의 할 점은 변수의 값에 이름에 공백이 있으면 작동하지 않습니다.

아래 예에서 질문에 대답하려면 UPSTART_SESSIONGNOME_DESKTOP_SESSION_ID 만 필요합니다.

sudo_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 
} 
+0

@ dyorgio의 도움에 대해 구체적으로 언급하고 싶습니다. 그는 위의 솔루션의 50 % 인 또 다른 도움말 포럼에서'/ proc/$ pid/environ' 논리를 나에게 제공했습니다. 감사! – tresf

0

는이 콘텐츠와 /etc/sudoers.d에 새 파일을 작성해야합니다.

그래서, 완전한 해결책은 스크립트가이 파일을 만든 다음 다른 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 
+0

고마워요! 이것은'sudo -u foo'와 어떻게 조합 될까요? – tresf

+0

@QZSupport, 예, 대답이 업데이트되었습니다. – Dyorgio

+0

논리가 도움이되지만 문제가 해결되지 않습니다. 제안 된 수정은'rm -f' 라인을 주석 처리하고, 파일 이름을 하드 코딩하고, 설치 프로그램을 다시 실행하지 않는 한 도움이되지 않습니다. 이것은 이미 루트 권한이 있고 자체가 이미'sudo' 호출 안에있는 인스톨러입니다. 참고로 sudoers'README'에 따르면, echo를 호출하기 전에'umask 0337'을 사용해야합니다.하지만 너무 늦게 설정되어있는 것 같습니다. 설치 프로그램은 이미'sudo'로 시작되었고 환경 변수는 상실됩니다. – tresf