Bash

無法在腳本中列印位置參數

  • May 22, 2022

我正在使用這種方法打開一個 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/shrun 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"

在許多情況下,這會按您的預期工作;但不是一般的。一般來說,它和嵌入{}一樣有缺陷。單引號程式碼和後面的參數是正確的方法。

echo "remember: $1"; exec bash

很好,你在這裡雙$1引號。

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