Bash
無法在腳本中列印位置參數
我正在使用這種方法打開一個 Gnome 終端視窗並執行命令——在這種情況下,向我發送簡單的通知消息(將通過 安排
at
):#!/bin/sh gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash'
shell 只列印
remember:
字元串而不是我指定的值,例如在執行時remind.sh "pick up the package"
或remind.sh "buy groceries X and Y"
.當我將腳本剝離到其核心時,一切都按預期工作(當然,通過 cron 或 systemd 在自動化中沒有任何用處,因為前台沒有顯示任何內容):
#!/bin/sh echo "remember: $1"
分析
您(或者更確切地說
gnome-terminal
,在您的情況下)提供/bin/sh -c
的程式碼將看到程式碼之後提供的位置參數。例如這個gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash' zeroth first second …
將列印
remember: first
。當程式碼最終被解釋時,在程式碼導致
$1
(或$2
等$3
)擴展為空字元串之後不提供任何內容($0
有點不同,但這在這裡無關緊要)。這就是你得到的原因remember:
。/bin/sh
run bygnome-terminal
對主腳本的位置參數一無所知,除非你明確地傳遞它們。解決方案
要使用腳本的位置參數填充內部程式碼的位置參數,請使用
"$@"
代替first second …
:gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash' sh "$@"
你可以通過任何你想要的。這裡我們傳遞所有參數(
"$@"
擴展為所有位置參數),但一般可以使用(如果您希望內部程式碼只"$1"
知道第一個參數)或(如果您希望內部程式碼看到第二個位置參數)主腳本作為自己的)。"$2"
$1
筆記
sh
因為這裡解釋了第零個參數:第二個 sh 是sh -c 'some shell code' sh
什麼?- 如果在您的原始腳本(即沒有我的修復)中,您打算提供的 shell 程式碼
sh -c
是雙引號,那麼解釋腳本的 shell 將擴展$1
並將結果嵌入到內部程式碼中。不過不要這樣做。# 有缺陷 的 gnome 終端 -- /bin/sh -c "echo 'remember: $1'; exec bash"
在許多情況下,這會按您的預期工作;但不是一般的。一般來說,它和嵌入
{}
一樣有缺陷。單引號程式碼和後面的參數是正確的方法。
- 單引號程式碼確保它會按
/bin/sh -c
原樣(內部雙引號無關緊要)。然後sh
將看到程式碼為echo "remember: $1"; exec bash
很好,你在這裡雙
$1
引號。