Systemd

ExecStart=@/path/to/executable 上的 Systemd 服務前綴不會更改 argv000

  • August 21, 2022

根據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 $$**分別。

但是,當我使用pythonbash腳本執行服務時,**“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 程序的 與$0shell 腳本中的不同。即使在正常啟動腳本時也可以看到這一點:

$ 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等等。

引用自:https://unix.stackexchange.com/questions/714391