私は次の記事に基づいて、毎日17:00に冗長バックアップジョブを実行するシステムユーザーサービスを作成しました。Fedora 雑誌。私はGnomeデスクトップでFedora 28を実行しています。私のシステムタイマーの設定は次のとおりです。
[Unit]
Description=daily-backup timer
[Timer]
OnCalendar=*-*-* 17:00:00
Unit=daily-backup.service
Persistent=true
[Install]
WantedBy=default.target
この方法は、バックアップの実行中にマシンがシャットダウンしない限り、うまく機能します。このオプションを使用すると、次回ログインするとpersistent
すぐにバックアップが実行されます。残念ながら、ユーザーセッションがアクティブになる前にスクリプトが実行を試みるため、この時点ではバックアップスクリプトは失敗します。バックアップスクリプトは、バックアップディスクがまだマウントされていない場合は、まずマウントを試みます。
#!/usr/bin/env bash
USER=$(whoami)
MOUNTPOINT="/run/media/$USER/$2"
DEVICE=$(blkid -l -o device -t LABEL="$2")
if [ ! -d "$MOUNTPOINT" ]; then
gio mount --device $DEVICE
fi
# Call duplicity...
ただし、スクリプトはユーザーセッションがアクティブになるまでディスクをマウントできないようです。アクティブなセッションをポーリングすることでこの問題を解決できますが、これは問題に対する粗大な解決策です。
#!/usr/bin/env bash
USER=$(whoami)
MOUNTPOINT="/run/media/$USER/$2"
DEVICE=$(blkid -l -o device -t LABEL="$2")
# Poll for an active session
for i in {1..30}
do
SESSION_STATE=$(loginctl show-user "$USER" -p State --value)
[ "$SESSION_STATE" != "active" ] && sleep 1s || break
done
if [ ! -d "$MOUNTPOINT" ]; then
gio mount --device $DEVICE
fi
私はアクティブなユーザーセッションを要求するように私のsystemdユーザーサービスを構成する方法があるはずですが、これを行う方法がわかりませんでした。これが可能かどうかを知っている人はいますか?
答え1
USER=$(whoami)
(スクリプトの行から見ると)root以外のユーザーとしてこのサービスを実行しているようです(おそらくファイルUser=
に設定してdaily-backup.service
)。
systemd --user
サービスとタイマーデバイスを管理者が実行するユーザーサービスとして設定することを検討できます。
これを行うには、ディレクトリの下におよびを作成しますdaily-backup.service
。デフォルトでは、システムディレクトリに生成されたファイルはほとんど変更なく使用できます。 (該当する参照はあなたが設定したユーザーになりますので削除することができます。)daily-backup.timer
~$USER/.config/systemd/user/
User=
コマンドを使用してsystemctl --user ...
アクティブ化および開始し、ステータスを確認します。取り付け部分には以下を使用してください。
[Install]
WantedBy=default.target
ユーザー管理者はdefault.target
(例ではないmulti-user.target
)についてのみ知っているので、
起動時にユーザーセッションを開始するには、lingerを有効にするだけです。この場合、早く始まり、持続します。
loginctl enable-linger $USER
(文書参照loginctl enable-linger
.)
実際にあなたが言及したFedoraマガジンの記事を見ると、彼らはそう思うようです。 「タイマーによる自動化」のセクションについてはを参照してください$HOME/.config/systemd/user/
。
システムのユーザー単位についてもっと知りたい場合は、Arch Linux Wikiに良い資料があります。それに関する記事。
答え2
tl;dr (短い回答)
私は少なくとも基本的に使用可能な方法(システム単位ディレクティブなどの形式)はないと思います。しかし、これはsystemdの外でも確実に可能です。
長い答え
システムがイベントベースのトリガ(udevと同様の方法で)をサポートしたり、自動生成されたユニットファイルのカスタマイズを許可したりすることをお勧めします。これらの両方のアイデアを実装すると問題は解決しますが、実際には両方ともsystemdの長い欠点です。
このロジックを直接実装してみることができます。実際に何を達成したいのかを正しく理解している場合は、タイマーが実行されたときにセッションが無効になっている場合は、開始を「スキップ」するのとは対照的に、セッションがアクティブになるまで開始を「遅らせる」という意味が必要です。
デフォルトのアイデアは、システムバスからログインした状態変更イベントを受信し、それに応じてタイマーを開始/停止するシステムユーザーサービスでデーモンを起動することです。これはPythonで簡単に実装する必要があります(残念ながらD-Busから信号を受信するためのシェルフレンドリーなツールがないため、bashでは不可能です)。