Bash

如何自動完成以(涉及的別名)sudo 開頭的 shell 命令

  • December 1, 2020

假設一個在您的 中有以下別名.bashrc

alias docker='sudo docker'

然後嘗試docker run -v /tmp/test:/foo …在 bash 終端中自動完成,從docker run -v /tmp|開始 → 由於sudo別名中的存在,人們會得到以下分散注意力的行為:

$ docker 執行 -v /tmpTAB
$ docker run -v /tmp[sudo] 使用者密碼:

到那時,除了執行Ctrl+C和重新啟動之外,幾乎不可能進一步編輯命令行。

是否有解決方案來克服這種行為?即,保留sudo別名中的隱含含義,但在我們期望一些正常的自動完成時避免密碼提示。

一個獨立於alias功能的解決方案會很好(考慮到這裡提出的問題在$ sudo command …直接輸入任何內容時也會出現)。

依靠@ApolloXI 關於sudo -n並進行更多實驗的建議,我能夠克服我在之前的評論中提到的缺點。

綜上所述,在自動完成docker …命令時,會載入以下程式碼:

  • 從 /etc/bash.bashrc: . /usr/share/bash-completion/bash_completion;

  • 從 /usr/share/bash-completion/bash_completion:

    • __load_completion docker,
    • 然後. /usr/share/bash-completion/completions/docker;
  • 從 /usr/share/bash-completion/completions/docker:

    • docker version -f '{{.Client.Experimental}} {{.Server.Experimental}} {{.Server.Os}}, ETC。
    • 它重新執行docker命令(或別名,如果存在)。

因此,一個可行的解決方案只是用 bash 函式替換我的別名,檢測它是否是從 bash-completion 功能呼叫的。這可以通過讀取BASH_SOURCE數組來完成。

因此,我們可以採用以下解決方案:

docker() {
   if [[ "${BASH_SOURCE[*]}" =~ "bash-completion" ]]; then
       sudo -n docker "$@"
   else
       sudo docker "$@"
   fi
}

或者,如果我們希望能夠輕鬆禁用包裝器,請改為:

__docker() {
   if [[ "${BASH_SOURCE[*]}" =~ "bash-completion" ]]; then
       docker "$@"
   else
       sudo docker "$@"
   fi
}

alias docker=__docker

然後,sudo -n不再需要前綴,並且可以執行例如:

$ \docker run --help

如果您希望避免在 上出現密碼提示sudo,請嘗試該-n選項。

手冊頁sudo內容如下:

-n,–非互動式

> > 避免提示使用者進行任何類型的輸入。如果命令執行需要密碼,sudo 將顯示錯誤消息並退出。 > > >

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