Bash가 일부 명령에 대해 자동 완성을 비활성화하는 이유와 이를 활성화하는 방법은 무엇입니까?

Bash가 일부 명령에 대해 자동 완성을 비활성화하는 이유와 이를 활성화하는 방법은 무엇입니까?

특정 명령에 대해 자동 완성을 비활성화하는 bash를 자주 접합니다. 이로 인해 명령 이름에 임의의 기호를 추가하고 자동 완성을 사용한 다음 명령 이름을 수정해야 합니다. 이것은 매우 성가신 일입니다. 예를 들어:

# I type:
openvpn s<tab>
# Nothing happens, so I add x
openvpnx s<tab>
# Now this expands to
openvpnx somepath

# Same with ./configure or many other commands...

자동 완성이 항상 작동하도록 비활성화 기능을 비활성화하는 방법이 있습니까?

답변1

상장완료 현황

Bash/Readline이 명령을 완료하기 위해 사용하는 것을 볼 수 있습니다 complete -p command. 예를 들어 실행 complete -p openvpn하면

bash: complete: openvpn: no completion specification

이는 내 쉘이 사용하는 Readline에 특정 명령 완성 기능이 없으므로 openvpn기본적으로 파일 이름인 전통적인 완성 형식을 사용함을 의미합니다.

또 다른 예(정의 완료 시연):

$ complete -p dillo
complete -F _filedir_xspec dillo

이는 명명된 함수가 명령 완성을 _filedir_xspec제공하는 데 사용됨 을 나타냅니다 dillo.

완료된 콘텐츠 삭제

정의된 완성을 제거하려면 내장 옵션을 사용 -r하십시오 complete:

complete -r openvpn

답변2

배쉬는프로그래밍 가능한 완성. 1999년부터 파일 이름 완성이 아닌 명령 인수 완성을 조정할 수 있게 되었습니다. 명령별 완성이 구성되지 않은 경우 파일 이름이 기본값입니다. 따라서 명령을 로 변경할 때 파일 이름을 얻게 됩니다 openvpnx.

프로그래밍 가능한 완성은 일반적으로 /etc/bash_completion. 프로그래밍 가능한 완성이 전혀 필요하지 않고 파일 이름이 이해되지 않는 상황에서도 항상 파일 이름을 완성하려면 .bashrc.

openvpn명령 인수에 대한 사용자 정의 완성 기능이 있는 것 같은데 이 완성 코드는 첫 번째 인수에 대해 아무 것도 제공하지 않습니다. 왜 이런 일이 발생하는지 모르겠습니다. 완료 코드의 버그일 수 있습니다. 유용한 완료 코드 전체 옵션 및 해당 인수입니다. complete -p openvpn매개변수를 완성하기 위해 어떤 코드가 호출되는지 보려면 실행하세요 openvpn. 를 사용하여 이 사용자 정의 완성 코드를 비활성화할 수 있지만 complete -r openvpn, 그러면 파일 이름으로만 반환됩니다. 이는 openvpn몇 가지 옵션 이후의 명령줄에서만 유용합니다.

완성 설정에 관계없이 언제든지 다음을 호출하여 파일 이름을 완성할 수 있습니다.complete-filename(기본 바인딩: ) M-/대신 complete( TAB).

답변3

첫 번째 문제는 openvpn바이너리 파일 이름이 init.d 디렉터리의 항목과 일치한다는 것입니다.

complete | grep -i openvpn

생산하다

complete -F _service /etc/init.d/openvpn

Ubuntu 및 그 파생 제품에서 이는 /usr/share/bash-completion/bash_completion(패키지의 일부 ) bash-completion의 코드 에서 비롯됩니다.

for svcdir in ${sysvdirs[@]}; do
    for svc in $svcdir/!($_backup_glob); do
        [[ -x $svc ]] && complete -F _service $svc
    done
done

이 블록을 주석 처리하세요. Bash 인스턴스를 다시 시작합니다. openvpn자동 완성을 위해 TAB을 사용해 보고 실행해 보세요 .

complete | grep -i openvpn

이는

complete -F _openvpn /etc/init.d/openvpn

두 번째 질문은 에서 나왔습니다 /usr/share/bash-completion/completions/openvpn. /etc/openvpn에서 .conf 파일을 자동 완성하려고 시도하는데, 이는 /etc/openvpn 외부에 있는 일부 임시 구성 파일을 사용하여 openvpn을 실행하려고 하면 방해가 될 수 있습니다.

삭제하고 bash 인스턴스를 다시 시작하십시오.

sudo rm /usr/share/bash-completion/completions/openvpn

이제 openvpn 명령에 대한 표준 파일 완성을 얻으려면 Tab 키를 사용해야 합니다.

당신이 달리면

complete -p | grep openvpn

openvpn 이후 자동 완성을 시도하면 이제 다음과 같은 메시지가 표시됩니다.

complete -F _minimal openvpn`

더 나은 접근 방식은 openvpn의 bash 완료 스크립트를 수정/확장하는 것입니다. 그러나 그것은 또 다른 날의 이야기입니다.


bash-completion나중에 패키지의 원래 상태 로 되돌리려면 다음 명령을 사용하여 다시 설치하세요.

apt-get install --reinstall bash-completion

답변4

내 대답 중 슬픈 부분은 bash에서 (readline을 통해) 완료할 수 있는 가능성이 많다는 것입니다. 그러나 일반적인 Linux 배포판은 [tab](또는 [tab][tab])을 추가하여 기본 파일 이름 확장자를 방해할 수 있습니다.옵션 확장. 내 경우에는 그렇지패키지 "bash-완성"이것은 원래 질문에 설명된 동작을 제공합니다.

이것은 단순한 질문이 아닙니다 openvpn. Q는 "예를 들어"라고 말했습니다.

나는 bind -p | grep complete얻다:

"\C-i": complete
"\e\e": complete
"\e!": complete-command
"\e/": complete-filename
...
"\e\C-i": dynamic-complete-history
"\eg": glob-complete-word
"\e*": insert-completions
# menu-complete (not bound)
...
"\C-x/": possible-filename-completions

이곳은TAB=ctrl-i기본 기능으로 바인딩합니다 complete. 방금 Archlinux에서 다른 바인딩을 시도했습니다. "ta[esc][star]"를 사용하면 명령줄에 "ta"로 시작하는 모든 명령을 삽입할 수 있습니다.

readline 기능은 completeman bash에 설명되어 있습니다:

완료 중

완료(탭)

해당 지점 이전의 텍스트에 대해 완성을 시도합니다. Bash는 텍스트를 완전한 것으로 처리하려고 시도합니다.바꾸다 (텍스트가 $로 시작하는 경우)사용자 이름(텍스트가 ~로 시작하는 경우), 호스트 이름(텍스트가 @로 시작하는 경우) 또는주문하다(별칭 및 함수 포함) 순서대로. 이들 중 어느 것도 일치하지 않는 경우,파일 이름 완료해 보세요.

나는 이것을 부분적으로만 재현할 수 있습니다. 내 생각에 man bash는 첫 번째 단어를 [탭]하는지, 두 번째, 세 번째 등을 탭하는지에 따라 다르다는 점을 언급하는 것을 잊어버린 것 같습니다.

내 집/직장 디렉토리에 "ba"로 시작하는 파일이 있습니다. 프롬프트에서 "ba[tab]"을 입력하면 이름은 표시되지 않고 badblocksfrom 명령 만 표시됩니다 bashbug. 이것은 현명한 행동입니다. 첫 번째 단어는 명령을 제공하고 다음 단어는 파일 이름입니다. "$[tab]"을 입력하면 멋진 변수 이름 목록이 표시됩니다.

사실, [탭]이라고 하면 [탭][탭]을 의미합니다. 그러나 우리는 이것에 너무 익숙해서 이 "완전한" readline 함수가 무엇을 하는지조차 알아차리지 못합니다. "전체" 변형을 사용하면 검색 대상(명령, 파일 이름, 변수)과 일치 항목이 여러 개일 때 목록이 처리되는 방식(가능성)을 제어할 수 있습니다.

이러한 readline 함수에는 다양한 기본 바인딩이 제공됩니다. 목록 함수와 기본 바인딩 man bash모두 . man readline확인하려면 위에서 바인드 -p를 사용하세요. 이는 이 문서의 기초이기도 합니다 ~/.inputrc. 방금 하나 만들었습니다(신비한 /etc/inputrc를 사용하여):

set colored-completion-prefix on
set colored-stats on

색상 통계를 통해 ls --color"bi[tab][tab]" 뒤에 "bind"는 흰색으로, "bison"은 녹색으로 표시되어 "bind"가 실행 파일이 아니라는 것을 알 수 있습니다. 내장... 명령 확장입니다... "bind"는 파일 이름도 아닙니다!).

set show-all-if-ambiguous on

이는 탭과 이중 탭을 제어합니다. 추가하고 입력한 후

cd s[tab]

모든 파일 이름의 색상 목록을 직접 얻습니다. 디렉토리, 링크, 일반 파일 등은 모두 고유한 색상으로 표시됩니다.

이것들행 변수 읽기bind -v.inputrc 변경 사항을 테스트하려면 "bash"를 사용하여 새 bash를 시작한 다음 종료하십시오. 아니면 다시 로그인하세요.

이것다음 레벨에 있습니다/usr/share/bash-completion

여기에는 주로 util-linux 및 systemd 패키지의 각 명령에 대한 스크립트가 포함되어 있습니다. 마운트(2Kb) 및 systemctl(13Kb) 파일이 있습니다. 파일 마운트는 흥미롭습니다. "-t"를 입력하면 /proc/filesystems가 표시됩니다.

일반적으로 "mount -t [tab]" 다음에 파일 이름을 얻습니다. "마운트" 파일을 얻은 후 ext2, ext3 및 ext4와 같은 파일 시스템 유형을 얻었습니다. 나 간다:

complete -r mount

이 기능을 제거하세요. (이것은 complete쉘 내장 명령입니다)

세 번째 레이어는 추가입니다."bash 완성" 패키지. 테스트를 위해 설치한 후 제거했습니다. 이 패키지를 사용하면 옵션과 패키지 이름을 확장하는 멋진 기능을 얻을 수 있습니다. "tar --[tab]"을 입력하면 모든 옵션이 표시됩니다. 그러나 파일 이름 확장자는 많은 집합체에서 누락되었습니다. AMD는 단지 아치리눅스에만 있는 것이 아닙니다.

이 bash-completion 패키지는 2000줄 스크립트 "bash_completion"과 많은 명령 파일을 제공했습니다. "tar"에는 700줄의 코드가 있으며 완벽하게 작동합니다. 따라서 이 문제를 해결하는 것은 해결책이 아닙니다.

complete이 [탭]의 모든 세부 사항에 정말로 관심이 있다면 맨 아래부터 시작하여 [탭] 이외의 다른 키에 바인딩 되지 않는 readline 함수 한두 개를 선택해야 합니다 . 위의 기본 구성은 작동하지만 [tab] 이외의 다른 구성은 사용한 적이 없습니다. 이제 올바른 키에 올바른 기능을 설정하고 싶습니다. 옵션을 포함하거나 포함하지 않고 bash-completion 패키지를 확장합니다.

관련 정보