Xorg에 의존하는 서비스 작성


30

에 대한 사용자 수준 서비스를 작성하려고하는데 redshiftXorg가 시작되어 실행될 때까지 기다려야합니다. 내 현재 서비스 파일은 다음과 같습니다.

[Unit]
Description=Redshift
After=graphical.target

[Service]
Environment=DISPLAY=:0
ExecStart=/bin/redshift -l 28:-13 -t 5300:3300 -b 0.80:0.91 -m randr
Restart=always

[Install]
WantedBy=default.target

그러나 Xorg가 시작하기 전에 시작하려고 시도한 후 나중에 수동으로 서비스를 시작해야합니다. 나는 잘못된 After=목표를 사용하고 있다고 생각 합니다. 힌트가 있습니까?

답변:


20

나는 이것을 연구하고 있었고 grawity의 대답은 오래된 것 같습니다. 이제 사용자 세션의 일부로 실행되는 systemd로 사용자 서비스를 설정할 수 있습니다. DISPLAY 및 XAUTHORITY (현재 아치 및 데비안 스트레치)를 설정할 수 있습니다.

시스템 수준 앱 (다시 시작 등)과 마찬가지로 프로세스 관리를 수행 할 때 데스크톱 자동 시작 파일 사용에 대한 이전 권장 사항에 비해 의미가 있습니다.

지금 가장 좋은 문서는 아치 위키입니다. 시스템 / 사용자

TLDR 버전;

  1. 원하는 * .service 파일을 만듭니다 ~/.config/systemd/user/
  2. 실행 systemctl --user enable [service](.service 접미사 제외)
  3. 선택적으로 systemctl --user start [service]지금 시작하기 위해 실행
  4. 작동 상태 systemctl --user status [service]를 확인하는 데 사용

다른 유용한 명령들.

  • systemctl --user list-unit-files -모든 사용자 단위를 봅니다.
  • s ystemctl --user daemon-reload-.service 파일을 편집하는 경우

-- 나중...

대부분의 세션 데몬을 systemd .service 파일로 업그레이드하고 변환했습니다. 그래서 몇 가지 추가 메모를 추가 할 수 있습니다.

로그인시 서비스를 실행하기위한 기본 후크가 없으므로 직접 트리거해야합니다. ~ / .xsession 파일에서 수행합니다.

systemctl --user import-environment PATH DBUS_SESSION_BUS_ADDRESS
systemctl --no-block --user start xsession.target

첫 번째 행은 일부 환경 변수를 시스템 사용자 세션으로 가져오고 두 번째 행은 대상을 시작합니다. 내 xsession.target 파일;

[Unit]
Description=Xsession running
BindsTo=graphical-session.target

내 xbindkeys.service를 예로 들어 보겠습니다.

[Unit]
Description=xbindkeys
PartOf=graphical-session.target

[Service]
ExecStart=/usr/bin/xbindkeys -n -f ${HOME}/projects/dotfiles/.xbindkeysrc
Restart=always

[Install]
WantedBy=xsession.target

2
예제 단위 파일을 제공 할 수 있고 장치가 DISPLAY 및 XAUTHORITY를 사용할 수있게하는 방법을 설명 할 수 있다면 허용 된 답변을 바꾸어 드리겠습니다.
mkaito

@mkaito 데비안이 Stretch를 릴리스하면 이것으로 살펴 보겠습니다. 나는 데비안 안정을 실행하고 그때까지 더 연주하기 위해 기다리고 있었다.
존 에이 켄 베리

@mkaito에서 github.com/systemd/systemd/blob/v219/NEWS#L194는 그것은 X11 세션 스크립틀릿 지금 제공되는 "말한다 업로드 $ DISPLAY와의 환경에 $ XAUTHORITY systemd --user 데몬 세션을 시작합니다. 이는 시스템화 된 사용자 서비스로 실행되는 X11 지원 애플리케이션과의 호환성을 개선해야합니다. "
josch

특별한 단위가 필요한지 명확히하기 위해 예제 단위 파일을 계속보고 싶습니다.
mkaito

11

일반적인 힌트는 "하지 마십시오"입니다. redshift시스템 전체 서비스가 아닙니다. 각 세션마다 별도의 인스턴스가 있으며 특정 세션의 Xorg에 연결하는 방법에 대해 알아야합니다.

(Xorg는 시스템 서비스도 아닙니다. 디스플레이 관리자 만 있고 각 세션마다 별도의 Xorg를 시작합니다. // graphical.target디스플레이 관리자가 준비 될 때 알려 주지만 DM이 실제로 시작되는 시점에 대해서는 아무 것도 알려주지 않습니다. 첫 번째 또는 모두 – 표시됩니다.)

로 그냥 부팅을 시작하는 DISPLAY=:0이 주어진 시간에 정확히 하나의 디스플레이가 있다는 보장은 없으며, 항상 것을 위해 충분하지 않습니다 :0으로 Xorg가 오래된 잠금 파일을 떠나 충돌하는 경우 (예를 들어, 다음 하나에서 실행됩니다 :1그것으로 :0여전히 점유되어 있다고 생각합니다 ); XAUTHORITYX11에 인증이 필요하므로 파일 경로를 설정 해야합니다. 하고 있는지 확인하십시오 redshift당신이 이제까지 로그 아웃 및 다시 로그인하면 다시 시작됩니다.

시작하는 방법? 거의 항상 데스크탑 환경에는 자체 세션 서비스 를 시작하는 몇 가지 방법이 있습니다. 두 개의 일반적인 게시물 을 이미 설명한 이전 게시물참조하십시오 . ~/.xprofile스크립트와 ~/.config/autostart/*.desktop위치.

startx 를 사용 하면 ~/.xinitrc그러한 작업을 시작할 수 있습니다 . 독립형 창 관리자에는 종종 자체 시작 / 초기 스크립트가 있습니다. 예 ~/.config/openbox/autostart를 들어 Openbox의 경우.

이 모든 방법에 공통적 인 것은 프로그램이 세션 에서 시작 되어 위에 나열된 모든 문제를 피한다는 것입니다.


레드 시프트는 시스템 전체의 서비스가 아니지만 많은 경우 OP가하려고하는 사용자 서비스 인 것이 합리적입니다.
simotek 2016 년

5

다음은 아직 구할 수없는 graphical-session.target(쿠분투 16.04 시스템에서) 해결 방법으로 만든 것입니다 .

  1. graphic-session.target을 위아래로 가져 오는 의사 시스템 사용자 단위 를 작성하십시오 .

~/.config/systemd/user/xsession.target다음 내용으로 작성하십시오 .

[단위]
설명 = Xsession 시작 및 실행
BindsTo = graphical-session.target

이 새로운 장치에 대해 systemd에게 알려주십시오.

$> systemctl --user daemon-reload
  1. 현재 사용 가능한 Ubuntu 16.04 데스크탑을 통해 via 를 제어하는 자동 시작 및 종료 스크립트 를 만듭니다 xsession.target.

~/.config/autostart-scripts/xsession.target-login.sh다음 내용으로 작성하십시오 .

#! / bin / bash

만약 ! systemctl --user is-active xsession.target &> / dev / null
그때
  / bin / systemctl --user import-environment DISPLAY XAUTHORITY
  / bin / systemctl-사용자 시작 xsession.target
fi

~/.config/plasma-workspace/shutdown/xsession.target-logout.sh다음 내용으로 작성하십시오 .

#! / bin / bash

systemctl --user is-active xsession.target &> / dev / null 인 경우
그때
  / bin / systemctl --user stop xsession.target
fi

스크립트를 실행 가능하게 만드십시오.

$> chmod + x ~ / .config / autostart-scripts / xsession.target-login.sh
$> chmod + x ~ / .config / plasma-workspace / shutdown / xsession.target-logout.sh

참고 : 이 두 파일은 KDE가 자동 시작 및 종료를 위해 선택하는 곳에 배치됩니다. 파일은 다른 데스크탑 환경 (예 : Gnome)을위한 다른 위치에있을 수 있지만 해당 환경에 대해서는 모르겠습니다.

참고 : 이 해결 방법에는 다중 데스크톱 세션이 지원되지 않습니다. graphical-session.target하나의 활성 X11 세션 만 머신에서 실행되는 한 올바르게 처리합니다 (그러나 대부분의 Linux 사용자의 경우).

  1. 바탕 화면에 로그인 한 상태에서 자신 만의 시스템 사용자 단위 를 작성 graphical-session.target하고 깨끗하게 실행하십시오.

예를 들어 @mkaito의 단위는 다음과 같아야합니다.

[단위]
Description = 레드 시프트
PartOf = graphical-session.target

[서비스]
ExecStart = / bin / redshift -l 28 : -13 -t 5300 : 3300 -b 0.80 : 0.91 -m randr
다시 시작 = 항상

( daemon-reload단위를 편집 한 후에 는 잊지 마십시오 !)

  1. 컴퓨터를 재부팅하고 로그인하여 장치가 예상대로 시작되었는지 확인하십시오
$> systemctl-사용자 상태 graphic-session.target
● graphic-session.target-현재 그래픽 사용자 세션
   로드 됨 :로드 됨 (/usr/lib/systemd/user/graphical-session.target; 정적; 공급 업체 사전 설정 : 사용 가능)
   활성 : Don 이후 활성 2017-01-05 15:08:42 CET; 47 분 전
     문서 : man : systemd.special (7)
$> systemctl-사용자 상태 ...

미래의 어느 날 (우분투 17.04가 될 것입니까?) 시스템이 graphical-session.target올바르게 자체 처리하므로 내 해결 방법이 더 이상 사용되지 않습니다 . 그 당시에는 자동 시작 및 종료 스크립트를 제거하고 xsession.target사용자 정의 사용자 장치를 그대로 유지하면 작동합니다.


나는 이것이 오래된 의견이라는 것을 알고 있지만 작업 공간> 시작 및 종료> 자동 시작 아래의 시스템 설정 앱을 통해 시작 / 로그인 스크립트를 추가 할 수 있습니다.
AmbientCyan

2

이 솔루션은 질문 작성자가 요구하는 내용을 정확하게 수행합니다.

Xorg가 가동 될 때까지 기다려야합니다

다른 사용자가 이미 대답했듯이 더 나은 방법이있을 수 있지만 이것은이 문제에 대한 또 다른 접근법입니다.

특정 기준이 충족 될 때까지 차단 하는 systemd의 systemd-networkd-wait-online.service 와 유사합니다 . 이 서비스가 성공적으로 시작되거나 시간이 초과되면 이에 의존하는 다른 서비스가 시작됩니다.

매뉴얼 (섹션 "파일"), X 서버는 UNIX 소켓 생성합니다 /tmp/.X11-unix/Xn( n디스플레이 번호입니다).

이 소켓의 존재를 모니터링하여 특정 표시를위한 서버가 시작되었음을 확인할 수 있습니다.

confirm_x_started.sh:

#!/bin/bash
COUNTER=0

while [ 1 ]
do
  # Check whether or not socket exists
  if [ -S /tmp/.X11-unix/X0 ]
  then
    exit 0
  fi

  ((++COUNTER))

  if [ $COUNTER -gt 20 ]
  then
    exit 1
  fi

  sleep 0.5
done

x_server_started.service:

[Unit]
Description=Monitor X server start

[Service]
Type=oneshot
ExecStart=/path/to/confirm_x_started.sh

[Install]
WantedBy=example.target

이제 x_server_started.serviceX 서버와 동시에 시작할 수 있습니다.

다른 서비스 (X 서버를 시작해야 함)가 종속되도록 x_server_started.service

종속 단위 :

[Unit]
Description=Service that needs to have the X server started
Requires=x_server_started.service
After=x_server_started.service

[Service]
ExecStart=/path/to/binary

[Install]
WantedBy=example.target

X 서버가 문제없이 시작되면 x_server_started.service거의 즉시 시작되고 systemd는에 종속 된 모든 장치를 시작합니다 x_server_started.service.


이것은 잘 작동합니다. 추가 서비스는 훌륭합니다. 대상 서비스에서 ExecStartPre를 사용할 수도 있습니다. 'exit 0'전에 여분의 'sleep 1'을 추가해야했지만 X를 바로 잡아서 잡기에는 너무 빠릅니다.
TTimo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.