2016-07-09 64 views
2

我正在學習bash完成。我只能列出當前目錄的內容。這裏是我的代碼:如何在其他目錄中擴展bash完成?

_foo() 
    { 
     local cur prev opts 
     COMPREPLY=() 
     cur="${COMP_WORDS[COMP_CWORD]}" 
     prev="${COMP_WORDS[COMP_CWORD-1]}" 

     opts="push pull" 
     OUTPUT=" $(ls) " 

     case "${prev}" in 
      push) 
       COMPREPLY=($(compgen -W "--in --out" -- ${cur})) 
       return 0 
       ;; 
      --in) 
       COMPREPLY=($(compgen -W "$OUTPUT" -- ${cur})) 
       return 0 
       ;; 
     esac 

     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     return 0 
    } 
    complete -F _foo foo 

它的輸出是:

$ foo push --in[TAB] 
file1.txt file2.txt foo ;; content of pwd 

但是,當我這樣做:

$ foo push --in ~[TAB] 

它不工作。 所以我想知道如何在不同目錄下執行bash完成(不僅在pwd)?謝謝。

+0

哦,他們其實不是在腳本。這些僅僅是因爲Vim編輯器。我從那裏拷貝了這個腳本,所以行號也被複制了。 –

回答

2

您可以使用-f匹配文件名:

#!/bin/bash 
_foo() { 
     local cur prev opts 
     COMPREPLY=() 
     cur="${COMP_WORDS[COMP_CWORD]}" 
     prev="${COMP_WORDS[COMP_CWORD-1]}" 
     opts="push pull" 

     case "${prev}" in 
      push) 
       COMPREPLY=($(compgen -W "--in --out" -- ${cur})) 
       return 0 
       ;; 
      --in) 
       COMPREPLY=($(compgen -f ${cur})) 
       return 0 
       ;; 
     esac 

     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     return 0 
} 

complete -F _foo foo 

但是它似乎不單單~工作,但$ foo push --in ~/[TAB]作品和所有其他目錄 該解決方案不會包括斜線來尋找目錄文件:$ foo push --in /etc[TAB]會給foo push --in /etc並使用默認模式不foo push --in /etc/

下後解決了這個問題:
Getting compgen to include slashes on directories when looking for files

默認

使用輸入行的,如果compspec產生不匹配的默認文件名完成。

所以,你可以使用:

#!/bin/bash 
_foo() 
    { 
     local cur prev opts 
     COMPREPLY=() 
     cur="${COMP_WORDS[COMP_CWORD]}" 
     prev="${COMP_WORDS[COMP_CWORD-1]}" 

     opts="push pull" 
     OUTPUT=" $(ls) " 

     case "${prev}" in 
      push) 
       COMPREPLY=($(compgen -W "--in --out" -- ${cur})) 
       return 0 
       ;; 
      --in) 
       COMPREPLY=() 
       return 0 
       ;; 
      --port) 
       COMPREPLY=("") 
       return 0 
       ;; 
     esac 

     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     return 0 
    } 
    complete -o default -F _foo foo 

或設置爲默認模式,當你需要像這個帖子:https://unix.stackexchange.com/a/149398/146783

+0

這很好。但是如果我不想在特定情況下做任何事情。假設有一個參數--port,我想從鍵盤上取下它。它應該是這樣的 '$ foo push --port [TAB]' ;;自動完成應該停止,沒有結果。 它表示用戶從鍵盤傳入--port值。 但是通過你的回答,它會是 '$ foo push --port [TAB]' ;; pwd 的內容那麼有沒有什麼方法可以指定,我們在這些情況下不會默認結果? –

+0

但這不起作用。 '$ foo push --in [TAB] bash:compopt:command not found' 這是我得到的錯誤信息。 –

+0

您是否在bash_completion.d中輸入文件?嘗試在頂部添加'#!/ bin/bash'以確保它使用正確的bash。如果你的bash不在'/ bin/bash'中,換成右邊的bash位置('哪個bash') –