Shell

為什麼函式內部的別名不起作用?

  • July 25, 2019

請看下面的程式碼:

a()(alias x=echo\ hi;type x;alias;x);a

我在函式中有一個別名,我不想更改外部環境(這就是我使用()代替的原因{}),即使程式碼說別名已成功設置,它也不起作用,請檢查輸出:

x is aliased to `echo hi'
...
alias x='echo hi'
x: command not found

我聽說做shopt -s expand_aliases會解決,但它不僅沒有任何效果,而且我不能依賴,bash因為我正在使用dd-wrtbusyboxs ash

有人知道這個問題嗎?

如果您不反對使用eval

$ busybox ash -c 'a()(alias x=echo\ hi;type x;alias;eval x);a'
x is an alias for echo hi
x='echo hi'
hi

我不知道為什麼會這樣。

我不使用dash,但這是bash手冊對別名的說明:

關於別名的定義和使用的規則有些混亂。 Bash 在執行該行上的任何命令之前總是讀取至少一個完整的輸入行。別名在讀取命令時擴展,而不是在執行命令時擴展。因此,與另一個命令出現在同一行的別名定義在讀取下一行輸入之前不會生效。 該行別名定義後面的命令不受新別名的影響. 執行函式時,此行為也是一個問題。別名在讀取函式定義時擴展,而不是在執行函式時擴展,因為函式定義本身就是一個複合命令。因此,在函式中定義的別名在該函式執行之前不可用。為了安全起見,請始終將別名定義放在單獨的行中,並且不要在復合命令中使用別名。

另一個引述,這次來自zsh手冊:

以下程式碼說明了一個常見的別名問題:

          alias echobar='echo bar'; echobar

echobar這將列印一條找不到該命令的消息。發生這種情況是因為在讀入程式碼時會擴展別名;一口氣讀取整行,因此在echobar執行時為時已晚,無法擴展新定義的別名。 **這通常是使用 sourceor.**執行的 shell 腳本、函式和程式碼中的問題。因此,建議在非互動式程式碼中使用函式而不是別名。

我很確定它在其他貝殼中也很相似。

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