2016-09-21 3 views
1

bash 스크립트에서 폴더 이름을 자동 완성하려고합니다. 전체 폴더 이름을 입력하면 모든 것이 작동하지만 이름을 자동 완성하는 방법을 모르겠습니다. 어떤 아이디어? bash 스크립트에서 자동 완성

repo() { 
cd ~/Desktop/_REPOS/$1 
} 

나는 아이디어를 this SO post을 읽는 시도했지만 난 여전히 비난하는 비교적 새로운이기 때문에 빨리 잃었다.

목표 (되찾기 기능이 위의 내 bashrc에 포함 포함) : 사실

>ls ~/Desktop/_REPOS/ 
folder1 
hellofolder 
stackstuff 

>repo sta[TAB] fills in as: repo stackstuff 

답변

8

당신이 geirha's answer에서 코드의 꽤 빌릴 수 :

# this is a custom function that provides matches for the bash autocompletion 
_repo_complete() { 
    local file 
    # iterate all files in a directory that start with our search string 
    for file in ~/Desktop/_REPOS/"$2"*; do 
     # If the glob doesn't match, we'll get the glob itself, so make sure 
     # we have an existing file. This check also skips entries 
     # that are not a directory 
     [[ -d $file ]] || continue 

     # add the file without the ~/Desktop/_REPOS/ prefix to the list of 
     # autocomplete suggestions 
     COMPREPLY+=($(basename "$file")) 
    done 
} 

# this line registers our custom autocompletion function to be invoked 
# when completing arguments to the repo command 
complete -F _repo_complete repo 

for 루프 반복 모든 파일 _repo_complete 함수에 대한 두 번째 인수로 주어진 문자열로 시작하는 디렉토리 (이것은 자동 완성 될 문자열입니다).

.bashrc에 코드를 추가하면 올바르게 작동합니다.

+0

나는() '함수를'REPO를 제거하고 _repo_complete''내부의 코드를 삽입하고 싶었다면 (하나 개의 기능을 얻을 수), 나는 그것을 어떻게 할 것인가? – Rilcon42

+0

나는 마지막 줄을'complete -F _repo_complete'로 바꿀 수 있습니까? – Rilcon42

+0

필자는 자동 완성을 시도 할 때마다'_repo_complete' 함수가 호출되기 때문에 실용적이지 않다고 생각합니다. 이미 유효한 디렉토리 이름이 있는지 확인하여이 문제를 해킹하려고 시도 할 수는 있지만 엉망으로 인해 하나의 기능을 절약 할 가치가 없다고 생각합니다. – Euro

7

제대로 이해하면 사용자 정의 cd 명령에 대한 경로 자동 완성과 같은 두 가지 옵션이 제공됩니다.

  1. 당신은 당신의 CDPATH 환경 변수에 상위 디렉토리, ~/Desktop/_REPOS를 추가 할 수 있습니다

    CDPATH="$CDPATH":"$HOME"/Desktop/_REPOS 
    

    을 이제 임의의 디렉토리에서, 당신은 cd공간, 그리고 이외에를 입력 할 수 있습니다 현재 디렉토리의 하위 디렉토리에있는 모든 디렉토리가 ~/Desktop/_REPOS에 표시됩니다. (이 방법의 단점은 더 복잡합니다.)

  2. .bashrc에 완료 기능을 추가 할 수 있습니다. 시작한 방식에 따라 모든 디렉토리의베이스 이름이 ~/Desktop/_REPOS이 되길 원합니다.

    $ compgen -d "$HOME"/Desktop/_REPOS/ 
    /home/me/Desktop/_REPOS/folder1 
    /home/me/Desktop/_REPOS/folder2 
    /home/me/Desktop/_REPOS/stackstuff 
    /home/me/Desktop/_REPOS/hellofolder 
    

    이 모든 하위 디렉토리의 이름을 반환 디렉토리에 대한 자동 완성을 얻으려면, 우리는 compgen -d 내장을 사용할 수 있습니다.

    $ compgen -d "$HOME"/Desktop/_REPOS/f 
    /home/me/Desktop/_REPOS/folder1 
    /home/me/Desktop/_REPOS/folder2 
    

    는 basename이 제외한 모든 것을 제거하기 위해 우리는이 같은 쉘 매개 변수 확장, 사용 : 그것은 경로가보다 구체적인 경우 적은 수의 후보로 감소 매개 변수 확장에

    $ arr=(/path/to/dir1 /path/to/dir2) 
    $ echo "${arr[@]##*/}" 
    dir1 dir2 
    

    ##*/을 가장 긴 제거 각각의 요소가 arr*/과 일치 할 수 있습니다. 즉, 가장 가까운 슬래시 인 – 뒤에 오는 것만 남겨 둡니다.

    이제 우리는 이것을 함께 넣고 함수로 :

    _comp_repo() { 
        # Get list of directories 
        # $2 is the word being completed 
        COMPREPLY=($(compgen -d "$HOME"/Desktop/_REPOS/"$2")) 
    
        # Reduce to basenames 
        COMPREPLY=("${COMPREPLY[@]##*/}") 
    } 
    

    이 함께 repo와 함께 자동 완성을 위해 사용하는 명령으로, 당신의 .bashrc로 전환 :

    complete -F _comp_repo repo 
    

    공지 사항 당신의 repo 함수는 $1 인수를 인용 부호로 묶어 특수 문자 (공백, 탭 ...)가있는 디렉토리 이름을 올바르게 처리해야합니다.

    repo() { 
        cd ~/Desktop/_REPOS/"$1" 
    } 
    

당신이 을 공격 한 횟수 show-all-if-ambiguous 같은 readline settings에 따라 달라집니다.


참조