systemd initスクリプトは作業ディレクトリを作成します

systemd initスクリプトは作業ディレクトリを作成します

要求に応じてプログラムを実行するためのシステムスクリプトを作成しています。実行すると、作業ディレクトリが存在しない可能性があります。したがって、このディレクトリをスクリプトの一部にしたいと思います。ただし、指定された作業ディレクトリが存在しないため、エラーが発生します。

[Service]
User=Inplant
Group=Inplant
ExecStartPre=/bin/mkdir -p /home/inplant/IPSdevice/JAI1
WorkingDirectory=~/IPSdevice/JAI1
ExecStart=~/IPSdevice JAI1 

システムスクリプトの一部として作業ディレクトリを作成する方法はありますか?次のプログラムを実行したいと思います。

mkdir ~/IPSdevice/JAI1; cd ~/IPSdevice/JAI1; ~/IPSdevice JAI1

チルダをパスに変更することで、最初の問題を解決できました。今、別の問題が発生しました。

    Aug 06 09:48:53 ubuntu systemd[1]: Started JAI Device Service.
-- Subject: Unit app-ips-jai1.service has finished start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit app-ips-jai1.service has finished starting up.
-- 
-- The start-up result is done.
Aug 06 09:48:53 ubuntu systemd[103782]: app-ips-jai1.service: Failed at step CHDIR spawning /home/inplant/IPSdevice/IPSdevice: No such file or directory
-- Subject: Process /home/inplant/IPSdevice/IPSdevice could not be executed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- The process /home/inplant/IPSdevice/IPSdevice could not be executed and failed.
-- 
-- The error number returned by this process is 2.

システムスクリプトは次のとおりです。

[Unit]
Description=JAI Device Service
# When systemd stops or restarts the app.service, the action is propagated to this unit
PartOf=app.service
# Start this unit after the app.service start
After=app-ips.service

[Service]
# Pretend that the component is running
RuntimeDirectory=IPS-JAI1
User=inplant
Group=inplant
ExecStartPre=mkdir -p /home/inplant/IPSdevice/JAI1
WorkingDirectory=/home/inplant/IPSdevice/JAI1
#ExecStart=/home/inplant/IPSdevice JAI1 > /dev/nul 2>&1 & echo $! > /var/run/jai1.pid
ExecStart=/home/inplant/IPSdevice/IPSdevice JAI1
# Restart the service on non-zero exit code when terminated by a signal other than SIGHUP, SIGINT, SIGTERM or SIGPIPE
#Restart=on-failure

[Install]
# This unit should start when app.service is starting
WantedBy=app-ips.service

通常、「inplant」ユーザーとしてログインし、次のコマンドを実行してサービスを開始します。

cd ~/IPSdevice
mkdir -p JAI
cd JAI
../IPSdevice JAI

ベストアンサー1

問題の一部は、~拡張されていないsystemdを使用している~ため~user、コマンドにフルパスを指定する必要があることです。

また、systemdはコマンドを実行する前に確認するため、実際にディレクトリを作成してExecStartPre=使用することはできません。 (実際には、すべてのコマンドは同じディレクトリで実行されます。)WorkingDirectory=WorkingDirectory=ExecStartPre=

これを実現するには、シェルスクリプトを使用してExecStart=環境とexecデーモンを準備します。

たとえば、次のいずれかを作成します/home/inplant/start_inplant.sh

#!/bin/sh
set -eu
mkdir -p /home/inplant/IPSdevice/"$1"
cd /home/inplant/IPSdevice/"$1"
exec /home/inplant/IPSdevice/IPSdevice "$1"

ユニットファイルで以下を使用します。

[提供する]
ランタイムディレクトリ=IPS-JAI1
ユーザー=in vivo
グループ=インプラント
environment=LD_LIBRARY_PATH=/opt/pleora/ebus_sdk/Ubuntu-x86_64/lib:/opt/pleora/ebus_sdk/Ubuntu-x86_64/lib/genicam/bin/Linux64_x64:/opt/xview2_64/lib/:/opt /linux_x64
環境=GENICAM_ROOT_V3_0=/opt/pleora/ebus_sdk/Ubuntu-x86_64/lib/genicam
ExecStart=/home/inplant/start_inplant.sh JAI1
# SIGHUP、SIGINT、SIGTERM、SIGPIPE 以外のシグナルで終了した場合は、ゼロ以外の終了コードでサービスを再開します。
再開=失敗した場合

不要、またはWorkingDirectory=単位ExecStartPre=ファイルにありません。シェルスクリプト自体から環境変数をエクスポートすることを決定することもできます。どちらかを好むかどうかはユーザー次第です。

重要な部分は使用することですexecシェルスクリプトから。これにより、シェルは自分自身をランチャーに置き換え、プログラムはシェルの起動時と同じPIDで実行されます。これは、systemdがそのPIDを使用してデーモンを制御するため(たとえば、サービスの停止時にデーモンを終了するなど)、シェルスクリプトではなくデーモンになりたいので、重要です。また、何の理由もなくスペースだけを占める追加のシェルプロセスを実行したくありません。

ちなみにあなたは実際にできる~シェルスクリプトで使用してくださいstart_inplant.sh。これはシェルスクリプトであるため、シェルが通常行うすべての拡張を許可して実行します。


この質問に対する他の答えを参照してください。

これは実際には機能しません。

ExecStartPre=cd /home/inplant/IPSdevice/JAI1

systemdは実際にはシェルコマンドを実行しません(そしてcd組み込みシェルです)、これはバイナリがある場合にのみ機能しますが、そうではありません(ディレクトリの変更は現在のプロセスにのみ影響を/bin/cd与える/usr/bin/cdため、外部バイナリはそうではありません)それ自体にのみ影響します狂って終了するので効果が見られないので意味があります。)

シェルを使用して明示的にコマンドを実行する場合でも、次のようになります。

ExecStartPre=/bin/sh -c "cd /home/inplant/IPSdevice/JAI1"

これは現在のシェルにのみ影響し、ディレクトリ変更の効果は他のコマンド、特にこのExecStart=コマンドに伝播されないため機能しません。

何が起こっているのかわかりません。仕事文書ExecStartPre=なぜなら、コマンドが失敗すると、systemdは実際にはユニットファイルを実行しないからです。できるsystemdは構文が正しくないと思うので(最新バージョンまでsystemdバージョンでは実行するコマンドへのフルパスが必要です)、この行を無視して記録し、その行をスキップして次の行に移動します。

もしそうなら、あなたのデーモンは実行中であり、/home/inplant/IPSdevice/そうではありません。/home/inplant/IPSdevice/JAI1/おそらくそこではうまくいくでしょう。デーモン(特によく書かれたデーモン)は、自分が起動するディレクトリのどのデーモンにも興味がないので驚くことはありません。したがって、おそらくこの要件があるでしょう。そもそも存在しません。

また、このコマンドは次のとおりです。

ExecStartPre=/bin/chown inplant.inplant /home/inplant/IPSdevice/JAI1

既定では、コマンドはExecStartPre=指定された資格情報で実行されるため、そのユーザーとしてすでにディレクトリを作成しているため、不要です(特に、ユーザーにディレクトリを作成する権限が必要であることを意味します)。所有権の変更。これは、すでに作成されたディレクトリの所有権である必要があるためです。User=Group=mkdirinplant

おすすめ記事