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.