Systemdサービスがbashスクリプトを実行できない

Systemdサービスがbashスクリプトを実行できない

Arch Linuxで、次のBashスクリプトを実行するsystemdサービスを作成しようとしています。

#!/bin/bash

/bin/xbindkeys &
/bin/setxkbmap -layout gb

いくつかのオンライン指示を介してサービスを保存するためにmyfirst.service呼び出されるファイルを作成しました。/etc/systemd/systemファイルの内容は次のとおりです。

[Unit]
Description=Command Service

[Service]
ExecStart=/etc/startupjobscript
User=user1
Type=oneshot
Restart=on-abort
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

サービスは/etc/startupjobscriptBashスクリプトを実行する必要があります。その後、サービスを有効にして開始しました。

systemctl enable myfirst
systemctl start myfirst

しかし、何らかの理由で動作せず、まったくロードされ実行されていないことがわかりました。

編集:これsudo systemctl 状態 myfirst私に与える:

Warning: The unit file, source configuration file or drop-ins of myfirst.service changed on disk. Run 'systemctl daemon-reload' to reload units.
● myfirst.service - Command Service
     Loaded: loaded (/etc/systemd/system/myfirst.service; enabled; vendor preset: disabled)
     Active: failed (Result: exit-code) since Wed 2020-08-26 21:07:02 BST; 18min ago
    Process: 332 ExecStart=/etc/startupjobscript (code=exited, status=255/EXCEPTION)
   Main PID: 332 (code=exited, status=255/EXCEPTION)

Aug 26 21:07:01 archlinux systemd[1]: Starting Command Service...
Aug 26 21:07:02 archlinux startupjobscript[337]: Cannot open display "default display"
Aug 26 21:07:02 archlinux systemd[1]: myfirst.service: Main process exited, code=exited, status=255/EXCEPTION
Aug 26 21:07:02 archlinux systemd[1]: myfirst.service: Failed with result 'exit-code'.
Aug 26 21:07:02 archlinux systemd[1]: Failed to start Command Service.

ベストアンサー1

Xサーバーと通信するすべてを実行すると、systemdサービスは少しトリッキーになります。これを行う2つの主な方法があります。

  1. ユーザーサービスの実行
  2. 設定$DISPLAYして到達するまで開始しないでくださいgraphical.target

ユーザーサービスとして実行するには、にmyfirst.service移動し~/.config/systemd/system/てから削除し、User=WantedBy=設定しますdefault.targetdefault.targetユーザーがログインすると到着します。いつか、graphical-session.targetユーザーがデスクトップ環境にログインすると到着しますが、まだ利用できません。代わりに、default.targetユーザーがログインすると実行されます。ディスプレイマネージャを使用している場合は、以前にxセッションを持っていた可能性があります。

[Unit]
Description=Command Service
After=default.target

[Service]
ExecStart=/bin/xbindkeys
ExecStartPost=/bin/setxkbmap -layout gb
Type=simple
Restart=on-abort

[Install]
WantedBy=default.target

--userこのデバイスを使用するときは、次の方法を使用してください。

systemctl --user daemon-reload
systemctl --user start myfirst.service
systemctl --user enable myfirst.service

システムサービスとして保持するには、そのファイルをアーカイブして/etc/systemd/system/Xサーバーに接続できるように環境を設定する必要があります。結局は成功しなければなりませんWantedBy=graphical.target。これにより、Xサーバーが起動するまでXサーバーに接続しようとしません。しかし、ログインするまで.Xauthorityが有効であるかどうかわからないので、常に成功するかどうかはわかりません。

[Unit]
Description=Command Service
After=graphical.target

[Service]
ExecStart=/bin/xbindkeys
ExecStartPost=/bin/setxkbmap -layout gb
Type=simple
User=user1
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/user1/.Xauthority
Restart=on-abort

[Install]
WantedBy=graphical.target

複数のユーザーまたは複数のモニターがある場合は、システム全体のサービスが少し奇妙になる可能性があります。ユーザー固有のタスクを実行することをお勧めします。デスクトップ環境にいる場合は、これらの変数をどのように設定するかを把握echo $DISPLAYできます。echo $XAUTHORITY


systemdこれらの変更を行った後は、次の変更を試みる前にその内容を読んでくださいstart。ランニング:

systemctl daemon-reload

試してみたことがある場合は、systemctl disable myfirst.serviceまず試してみてsystemctl start myfirst.service効果があることがわかったら、続行しますsystemctl enable myfirst.serviceenable再起動すると、サービスが呼び出されるようにシンボリックリンクが作成されます。実験中にこれらのリンクを混乱させたくない場合は、再起動をテストする準備が整うまで有効にしないでください。default.targetgraphical.target


/bin/xbindkeys &ちなみに、私はあなたのbashスクリプトの対応する行について奇妙な疑問を抱いています。一般的にxbindkeys永遠に実行されますか?その場合は、ExecStart=次のように変更する必要があります。

ExecStart=/bin/xbindkeys
ExecStartPost=/bin/setxkbmap -layout gb
Type=simple

上記で提案した単位をこのように変更しました。

これにより、systemdはプロセスをフォークせずに直接追跡できます。Type=に設定されていないため、forkingbashスクリプトが終了し、systemdがPIDを追跡しないため、xbindkeysPIDを孤立したPIDとして残してこれを防ぐことはできません。xbindkeysこの操作の一部として退場した場合、ExecStartサービスを停止するとxbindkeysが終了します(今はこれを実行できないようです)。この場合は適用されなくなり、Type=simple設定する必要がありますoneshot

おすすめ記事