ExecStartでシェルコマンドを正しくエスケープする方法は?

ExecStartでシェルコマンドを正しくエスケープする方法は?

これを実行してください:

[Unit]
Description=Save a screenshot
Wants=screenshot.timer

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'DISPLAY=:0 scrot /home/myuser/Pictures/Journal/$(date +"%s").png'

[Install]

結果:

scrot: Saving to file /home/myuser/Pictures/Journal//usr/bin/zsh.png failed: No such file or directory

なぜ?シェルで同じコマンドを実行すると正常に動作します。

% /bin/sh -c 'DISPLAY=:0 scrot /home/myuser/Pictures/Journal/$(date +"%s").png'
% echo $?
0
% 

私が使用するコマンドは次のとおりです。

systemctl --user daemon-reload && systemctl --user start screenshot.service; systemctl --user status screenshot.service

答え1

systemdユニットは以下を利用できます。様々な「指定者」多くの分野の中で、その1つは次のとおりです%s

指定子 重要性 詳細
%s ユーザーシェル Service Managerインスタンスを実行しているユーザーのシェル。
%% 単一パーセント記号 %%代わりに%単一のパーセント記号を指定するために使用します。

%指定子によって解釈されるフィールドのsystemd単位でそれを使用する必要がある場合は、代わりに使用してください%%

関連情報