Bash

我在一個函式中的多個變數沒有被表示為別名。我認為我的語法有問題

  • May 5, 2020

bashrc中,我有這個警報功能,它可以採用 3 個變數:

a () {
   local $1="${1:-3600}"
  local $2="${2:-paa}"
  local $3="${3:-alarm}"
   sleep "$1" && $2 && $3
}
alias pah='pactl set-card-profile 0 output:hdmi-stereo'
alias paa='pactl set-card-profile 0 output:analog-stereo'
alias alarm='vlc ~/alarm.mp3'

在命令行上,以下命令可以很好地執行我的別名。

sleep 3600 && paa && alarm

但是,當我嘗試製作上面顯示的函式的這一部分時,我收到了這個錯誤:

bash: pah: command not found

還有: $ 1, $ 2、$3變數應該預設為3600paaalarm

我也很困惑如何編寫呼叫這個函式 $ 3 input, while allowing $ 1 美元和 2 美元將被預設。

IE

a null null alarm2

轉發注意:我在 Stack Overflow 上發布了這個,但意識到這個問題可能屬於 Unix 和 Linux 堆棧交換。

我看不出您如何從執行中獲得此輸出a:您是否發布了不同版本的輸出?但無論如何,我確實看到程式碼有什麼問題。

第一個問題是它local $1=…沒有做你認為它做的事情。它設置一個名稱為第一個參數的變數,它不設置第一個參數。例如,如果您呼叫函式 as a foo,則第一行將局部變數foo設置為 value foo。如果你a不帶參數打電話,你會得到

bash: local: `=3600': not a valid identifier

(以及更多錯誤),因為左側=是一個空字元串,而空字元串不是變數的有效名稱。

您不能使用賦值語法來設置編號參數:local 1=…也不起作用。您需要為變數命名或使用set內置函式一次設置所有編號的參數。

a () {
   local delay="${1:-3600}"
   local first_command_to_split_and_glob="${2:-paa}"
   local second_command_to_split_and_glob="${3:-alarm}"
   sleep "$delay" && $first_command_to_split_and_glob && $second_command_to_split_and_glob
}

第二個問題是別名僅在它們顯式出現在命令開頭時才會被擴展。它們不是從某些其他擴展的結果(例如獲取變數的值)中擴展而來的。

call 還有一個問題$first_command_to_split_and_glob,就是它只在簡單的情況下有效。它在空格處拆分變數的值(即傳遞給函式的參數),然後將每個部分解釋為萬用字元模式,如果該模式與至少一個文件名匹配,則將其擴展。例如a 2 'cat "file name with spaces"',嘗試顯示名為"filenamewith的文件的內容spaces"。引號之外的變數擴展應用“split+glob”操作:它既不產生變數的值也不對值執行評估,而是一些很少有用的中間值。請參閱為什麼我的 shell 腳本會因空格或其他特殊字元而窒息?更多細節。

要解決這兩個問題,eval請在字元串上使用。注意周圍的雙引號"$first_command""$second_command"避免拆分+全域。

a () {
   local delay="${1:-3600}"
   local first_command="${2:-paa}"
   local second_command="${3:-alarm}"
   sleep "$delay" && eval "$first_command" && eval "$second_command"
}

最後,要傳遞一個空參數,請使用引號分隔一個空字元串。例如:

a '' pah

等待 3600 秒,然後執行pah,然後執行alarm

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