この違いがプログラム間で何であるかについて私は興味があります。 systemctlで有効にしたときにsystemdで開始した場合と、/etc/rc.local
またはCLIで開始した場合の比較.
たとえば、私は最近、Raspberry Piにshairport-syncを使用していました。最初に、Sudo systemctl enabled shairport-syncを使用してshairport-syncを開始するように設定しました。
後で、shairport-sync
内の機能を使用して、接続するデバイスに事前およびポストしてスクリプトを実行しました。
驚いたことに、shairport-sync
によって実行されたスクリプトはkill
arecord
またはaplay
を実行しませんでした
しかし、ターミナルからスクリプトを実行すると、スクリプトが実行され、arecord
とaplay
が強制終了されました。
さらに混乱させるために、私はshairport-sync
を強制終了し、ターミナルから起動して、何が起こっているのかを確認しました。そうすると、デバイスが接続してarecord
とaplay
を強制終了したときにスクリプトが期待どおりに機能しました。そこで、修正としてsysmtectl
のshairport-sync
を無効にし、/etc/rc.local
で実行するように設定しました。 reboot
の後は、期待通りに機能しました。
これにより、systemd
の一部として実行されるプログラムと、/etc/rc.local
またはCLIから起動したときに実行されるプログラムには、いくつかの違いがあると私は思います。
なぜこれが起こるのですか?これは、実行レベルが異なるためですか?ダークマジック?
デバイスがshairport-sync
に接続するときに実行されるスクリプトは次のとおりです:shairportstart.sh
#!/bin/sh
/usr/bin/Sudo /bin/pkill arecord
if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then
/usr/bin/amixer set Speaker 40%
else
/usr/bin/amixer set Speaker 100%
fi
/home/pi/shScripts/shairportfade.sh&
exit 0
これがフェードスクリプトです:shairportfade.sh
#!/bin/sh
/usr/bin/amixer set Speaker 30-
for (( i=0; i<30; i++))
do
/usr/bin/amixer set Speaker 1+
done
exit 0
デバイスがshairport-sync
に切断したときに実行されるスクリプトは次のとおりです:shairportend.sh
#!/bin/sh
/usr/bin/amixer set Speaker 70%
/usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat&
exit 0
systemd
の一部としてshairport-syncが最初に実行されたときにのみ、/var/log/syslog
に次のエラーが見つかりました。 shairport-sync
がCLIまたは/etc/rc.local
から実行されたとき、エラーはありませんでした。
Jan 24 00:38:45 raspberrypi shairport-sync[617]: Sudo: no tty present and no askpass program specified
唯一の違いは、デバイスが接続または切断したときにshairport-sync
が最初にどのように開始されるかであり、shairport-sync
が引き続き実行されることに注意してください。
「systemdでの動作が異なるのはなぜですか?」のバリエーションはよくある質問です。
SystemdからではなくCLIから何かが実行されるときはいつでも、違いを説明する可能性のいくつかの広いカテゴリーがあります。
systemd
は、それが渡す環境変数を_man systemd.exec
_でセクション 生成されたプロセスの環境変数 に記述します。違いを自分で調べたい場合は、_systemd-run /path/to/binary
_を使用できます。これは、systemdサービスによって実行されるため、アプリを一時的なスコープで実行します。 _Running as unit: run-u160.service
_のような出力が得られます。次に、_journalctl -u run-u160.service
_を使用して出力を確認できます。アプリを変更して、受け取った環境変数をダンプし、CLIの実行とsystemdの実行を比較します。アプリが適切に変更されていない場合は、_systemd-run env
_を使用して渡される環境変数を確認し、その結果のジャーナルログを確認できます。 X11 GUIアプリを起動しようとしている場合は、 DISPLAY
環境変数を設定する必要があります 。その場合は、systemd
ではなく、デスクトップ環境の「自動起動」機能の使用を検討してください。man systemd.resource-control
_ を参照してください。 _systemctl show your-unit-unit.service
_を使用して、開始しようとしているサービスに影響を与える完全な構成値を確認します。bash
CLI環境は対話型ログインシェルです。 systemd
にはない_.bashrc
_などのソースファイルがあります。これらのスクリプトは、環境変数の設定に加えて、SSHエージェントが接続してSSHアクションがログインを必要としないようにするなど、他の多くのことを実行できます。参照 ログインシェルと非ログインシェルの違い?Sudo
やssh
などの一部のプログラムがパスワードを要求するときに予期するTTYに接続されています。参照 Sudo:ttyが存在せず、askpassプログラムが指定されていないman systemd.service
_ に記載されているように、_ExecStart=
_の最初の引数はバイナリへの絶対パスである必要があります。systemd
のコマンドライン構文は非常に制限されています です。必要に応じて、シェルからコマンドを明示的に実行することにより、systemd
を使用してシェル構文を複製できる場合があります。ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
これは、システムがリソース制御を備えた一貫した環境でコードを実行する機能です。これにより、ハードウェアを圧倒することなく、長期的に再現性のある安定した結果を得ることができます。