man systemd.service
プレフィックスの取扱説明書によると、@
次のようになります。
実行ファイルパスに "@" プレフィックスが付いている場合、2 番目に指定されたトークンは "argv[0]" (実際のファイル名の代わりに) として実行プロセスに渡され、その後に指定された追加引数が続きます。
ただし、bashスクリプトまたはpythonスクリプトを使用してサービスを実行すると、ファイル名またはargv [0]は機能しません。これは、C言語で書かれたプログラムを使用している場合にのみ機能します。
私のサービスには次のものがあります。
[Unit]
Description=After service Number: 1
[Service]
Type=oneshot
ExecStart=@/home/edgar/bin/script "after-1-service" "1" "Args from after-service"
[Install]
WantedBy=multi-user.target
以下を使用してこのサービスを実行するとき氏プログラムファイル名の値は次のとおりです。「1時以降サービス」その他のパラメータ(「1」、「アフターサービスのパラメータ」)は、次のように正しく渡されます。パラメータ[1]そしてパラメータ[2]それぞれ。
しかし、私が使用してサービスを実行するときPythonまたは強く打つスクリプト値「1時以降サービス」効果がなく、スクリプトのデフォルトのファイル名を印刷します。パラメータ「1」と「Args from after-service」は、次のように正しく渡されます。パラメータ[1]そしてパラメータ[2]それぞれ。
Pythonとbashスクリプトの場合はどうなりますか?「1時以降サービス」議論?これは、filename または argv[0] が無視された場合に渡す必要があると思うからです。「1時以降サービス」argv[1] のように、他の引数は次のようになります。パラメータ[2]そしてパラメータ[3]
c
ファイル名を印刷するために作成したコードは次のとおりです。
printf("Filename: %s\n",argv[0]);
これは私が書いたコードですpython
。
print(f"Filename: {sys.argv[0]}")
これは私が書いたコードですbash
。
echo Filename $0
私はシンボリックリンクとファイル名の変更でスクリプトを正しくテストしたので、これはCプログラムにのみ適用されるか、systemd(バージョン251)のバグである可能性があると思います。
答え1
ここでの問題は、シェルプロセスのプロセスがシェルスクリプト内のプロセスと同じではないことですargv[0]
。$0
これは通常の起動スクリプトでも見ることができます。
$ cat argv0.sh
#!/bin/sh
echo "Filename $0"
$ sh ./argv0.sh
Filename ./argv0.sh
シェルはexecve("/bin/sh", ["sh", "./argv0.sh"], [env vars...])
ie argv[0]
gets set toのようなものを呼び出すでしょうsh
。しかし、スクリプトの名前$0
はスクリプト実行後、マニュアルページは次のように言います。
0
シェルまたはシェルスクリプトの名前に展開されます。これはシェルが初期化されるときに設定されます。 bashがコマンドファイルを使用して呼び出されると、$0
ファイル名に設定されます。 」
機能に関する限り、名前が何であるかは重要ではありません。通訳に設定されています。
私はこの質問が原則としてPythonに似ていると思います。たとえば、マニュアルには次のように記載されています。
sys.argv
Pythonスクリプトに渡されたコマンドライン引数のリスト。argv[0]
スクリプト名(オペレーティングシステムに応じてフルパス名ではない)。
しかし、Python 3.10には、sys.orig_argv
あなたが探しているものと同じ機能もあります。
sys.orig_argv
Python実行可能ファイルに渡されたコマンドライン引数の生のリスト。
シェルが起動すると、sh -c "code..." arg0 arg1 ...
コードの後の最初の引数がに割り当てられます。$0
これを使用して、次のようにコードを実行できます。
$ sh -c '. ./argv0.sh' foobar
Filename foobar
同じ内容などを. ./argv0.sh
表示できるように、同じシェルでスクリプトを実行するために使用されます。$0