私は、このプログラム間の違いが何であるかについて興味があります。 systemctlで有効にした場合はsystemdで開始しましたが、/etc/rc.local
で開始した場合は またはCLIを介して。
たとえば、私は最近、ラズベリーパイにshairport-syncを使用していました。最初に、sudosystemctl対応のshairport-syncを使用してshairport-syncを開始するように設定しました。
その後、shairport-sync
内の機能を使用しました 接続するデバイスの前にスクリプトを実行し、デバイスに投稿します。
驚いたことに、shairport-sync
によって実行されたときのスクリプト kill
しませんでした arecord
またはaplay
ただし、ターミナルを介してスクリプトを実行すると、スクリプトが実行され、arecord
が強制終了されました。 およびaplay
。
さらに混乱させるために、私はshairport-sync
を殺しました ターミナル経由で起動して、何が起こっているのかを確認しました。そうすると、デバイスが接続してarecord
を強制終了したときに、スクリプトが期待どおりに機能しました。 およびaplay
。そこで、修正としてshairport-sync
を無効にしました sysmtectl
で /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
/var/log/syslog
で次のエラーが見つかりました shairport-syncが最初にsystemd
の一部として実行された場合のみ 。 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環境はインタラクティブログインシェルです 。.bashrc
のようなソースファイルがあります そのsystemd
していません。これらのスクリプトは、環境変数の設定に加えて、SSHエージェントを接続してSSHアクションにログインを必要としないなど、他の多くのことを実行できます。ログインシェルと非ログインシェルの違いも参照してください。 - TTYなし 。インタラクティブセッションは、
sudo
などの一部のプログラムが使用するTTYに接続されています。 およびssh
パスワードの入力を求めるときに期待します。 sudo:ttyが存在せず、askpassプログラムが指定されていない
も参照してください。 - 相対パスと絶対パス 。シェルでの相対的なバイナリ動作ですが、
man systemd.service
に記載されています。 、ExecStart=
の最初の引数 バイナリへの絶対パスである必要があります。 - 制限されたコマンドライン構文 。シェルCLIは多くのメタ文字をサポートしますが、
systemd
コマンドライン構文が非常に制限されています。必要に応じて、systemd
を使用してシェル構文を複製できる場合があります。 シェルを介してコマンドを明示的に実行する:ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
これは、システムがリソース制御を備えた一貫した環境でコードを実行する機能です。これは、ハードウェアを圧倒することなく、長期的に再現性のある安定した結果を得るのに役立ちます。
関連:このプロセスSTATは何を示していますか?