ExecStart=@/path/to/executable 上的 Systemd 服務前綴不會更改 argv000
根據
man systemd.service
使用前綴的手冊@
說:如果可執行路徑以“@”為前綴,則指定的第二個令牌將作為“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
當我使用c程序執行此服務時,文件名採用**“after-1-service”的值,而其他參數(“1”,“Args from after-service”)作為****argv正確傳遞$$ 1 $$和argv$$ 2 $$**分別。
但是,當我使用python或bash腳本執行服務時,**“after-1-service”的值不起作用並列印腳本的主文件名,並且參數“1”和“來自售後服務的 Args”被正確傳遞作為argv$$ 1 $$和argv$$ 2 $$**分別。
在 python 和 bash 腳本的情況下,**“after-1-service”**參數發生了什麼?因為如果文件名或 argv
$$ 0 $$被忽略我想它應該作為 argv傳遞給**“after-1-service”$$ 1 $$並且其他參數應該作為argv$$ 2 $$和argv$$ 3 $$**
c
這是我為列印文件名而編寫的程式碼:printf("Filename: %s\n",argv[0]);
這是我寫的程式碼
python
:print(f"Filename: {sys.argv[0]}")
這是我寫的程式碼
bash
:echo Filename $0
我已經使用符號連結和文件名更改正確地測試了這些腳本,所以我猜這僅適用於 c 程序,或者它可能是 systemd(版本 251)的錯誤。
這裡的問題是
argv[0]
shell 程序的 與$0
shell 腳本中的不同。即使在正常啟動腳本時也可以看到這一點:$ cat argv0.sh #!/bin/sh echo "Filename $0" $ sh ./argv0.sh Filename ./argv0.sh
外殼呼叫類似的東西
execve("/bin/sh", ["sh", "./argv0.sh"], [env vars...])
,即argv[0]
設置為sh
。但是,在腳本中是執行的腳本的$0
名稱,手冊頁說:
0
擴展為 shell 或 shell 腳本的名稱。這是在 shell 初始化時設置的。如果使用命令文件呼叫 bash,
$0
則將其設置為該文件的名稱。"就該功能而言,解釋器的名稱設置為什麼並不重要。
我認為這個問題在原則上與 Python 相似,例如手冊說:
sys.argv
傳遞給 Python 腳本的命令行參數列表。
argv[0]
是腳本名稱(它是否為完整路徑名取決於作業系統)。但是,Python 3.10 也有
sys.orig_argv
它看起來可能是您正在尋找的東西:
sys.orig_argv
傳遞給 Python 執行檔的原始命令行參數列表。如果 shell 以 開頭
sh -c "code..." arg0 arg1 ...
,那麼程式碼之後的第一個參數將分配給$0
,因此您可以使用它並執行如下內容:$ sh -c '. ./argv0.sh' foobar Filename foobar
用於在同
. ./argv0.sh
一個 shell 中執行腳本,以便它看到相同的$0
等等。