이 옵션은 bash에서 쉘 완성을 생성할 때 -C
매우 강력하고 일반적으로 보입니다 . 이는 다음과 같이 정의됩니다:
-씨 주문하다
주문하다 서브셸 환경에서 실행되면 해당 출력이 가능한 완성으로 사용됩니다.
이건 정말 간단한 것 같아요. 그런데 이상하게도 그렇지 않습니다. 만약 내가한다면:
$ complete -C "echo one two three" test.sh
그런 다음 [tab]을 한 번 입력 test.sh
하고 클릭하면 행이 채워집니다.
$ test.sh one two three test.sh test.sh
물러서세요. 무엇? ! 비교하려고,
$ complete -W "one two three" test.sh
내가 기대했던 것과 정확히 일치합니다.하나,삼, 또는둘가능한 한 많이 작성하세요(물론 정렬된 순서대로).
어디에서도 좋은 문서를 찾을 수 없어서 시도해 보고 있습니다. 세미콜론이 도움이 될까요? complete -C "echo one two three;" test.sh
...아, 알았어, 도움이 됐어일부test.sh
, 마지막 이상한 부분을 제거하기 때문입니다. 하지만 여전히 완전한 문자열을 채웁니다 one two three
. 위의 설명이 "가능한 완성", 복수형으로 확실히 나와 있기 때문에 이것은 이상합니다. ...그럼, 음, 아, 개행 문자는요? 해 보자 complete -C "echo -e 'one\ntwo\nthree';" test.sh
.
그렇군요, 희망은 있습니다. 이것을 입력하면 test.sh [tab]
다시 돌아올 것입니다 one three two
. 그런데 상황이 잘못되었습니다. o
모호함을 해결하기 위해 하나를 추가하므로 , test.sh o[tab]
,저것반품
o one three two
이것은 수수께끼입니다. 실제로 내가 입력하는 모든 문자열이 목록에 추가됩니다. 이렇게 하면 응답을 test.sh wtf[tab]
받게 됩니다 . one three two wtf
뭔가 복잡한 일을 해야 할 것 같다고 생각했는데 compgen
, 역시 예상대로다 -W
. 그리고 사실
$ complete -W '$(echo one two three)' test.sh
echo
잘 작동합니다( 변경 가능한 결과를 생성할 수 있는 것보다 더 복잡한 작업을 수행하는 경우 조기 확장/실행을 방지하기 위해 작은따옴표에 유의하세요 ).
내가 여기서 무엇을 놓치고 있는 걸까요?
답변1
이 명령의 역할은 -C
완료 요청에 대한 응답으로 삽입할 텍스트를 결정하는 것입니다. 인터페이스가 조금 이상합니다.
인수는
-C
bash 스크립트 조각으로 해석됩니다. Bash는 이 코드 조각에 올바르게 인용된 세 개의 문자열을 추가합니다.- 인수가 완료되는 명령입니다.
- 커서가 위치한 단어의 접두사(커서까지).
- 커서 앞의 단어입니다.
일부 변수가 환경에 추가됩니다.
COMP_LINE
실행이 완료된 전체 행을 포함합니다.COMP_POINT
여기에는 커서 위치COMP_LINE
(0부터 계산)가 포함됩니다.COMP_TYPE
정상 완성은 9번, 모호한 완성에 대한 대안 나열은 33번, 메뉴 완성은 37번, 모호한 완성 간 전환은 63번, 부분 완료 후 나열 완료는 64번이다.COMP_KEY
완료를 트리거한 키를 포함합니다(예: 사용자가 누른 경우 tab Tab).
- 명령의 출력은 현재 단어를 대체하는 텍스트로 해석됩니다. 이는 추가된 접미사가 아닌 대체 접미사입니다. 명령은 지정된 접두사를 기준으로 필터링해야 합니다. 여기에는 여러 줄이 포함될 수 있으며, 이 경우 각 줄은 가능한 대체 줄로 간주됩니다.
이는 제공된 메커니즘과 거의 동일하지만 더 좋습니다.녹음된, 가 있는 함수의 경우 -F
. 함수의 인터페이스가 더 깔끔해졌습니다. 현재 명령의 단어 목록을 읽을 수 있습니다.COMP_WORDS
변수 및 현재 단어의 시작 위치COMP_CWORD
;그들은 결과를 다음과 같이 씁니다.COMPREPLY
대량으로.
유용한 인수(특히 완성할 접두사)가 명령 끝에 전달되기 때문에 이는 -C
거의 외부 명령에서만 사용할 수 있습니다 . 물론 비슷한 것을 사용할 수도 있지만 sh -c …
예쁘지는 않습니다.
complete -C 'sh -c '\'for x in one two three; do case $x in "$1"*) echo "$x";; esac''\'
답변2
complete
번거로운 외부 스크립트 및 함수 없이 정의 내에서 완성 기능을 유지하려는 경우 complete -C
이 옵션을 사용하는 가장 쉬운 방법은 명령 문자열 내에서 처리기 함수를 정의하는 것입니다. 내장 complete
함수는 아래와 같이 명령 문자열을 실행한 직후에 세 개의 문자열을 추가합니다.@Gilles "그러니 악한 행동은 그만하세요"그의 대답에서 그는 이렇게 말했습니다.
- 인수가 완료되는 명령입니다.
- 커서가 위치한 단어의 접두사(커서까지).
- 커서 앞의 단어입니다.
원래 질문의 예제 코드의 경우 가능한 완성을 접두사로 $2
포함하려면 위치 인수만 필요합니다. 가는 방법은 다음과 같습니다.grep
$2
complete -C 'makelist() { echo one; echo two; echo three; }; filter() { makelist | grep "^$2" | sort -u; }; filter' test.sh
test.sh t<tab>
를 입력하면 complete
공백이 포함된 명령 문자열이 마지막 문자열에 "test.sh", "t" 및 "test.sh"가 추가되어 실행됩니다 filter
. 이 명령은 다음을 수행합니다.
makelist
기능 정의filter
기능 정의filter
추가 문자열을 인수로 사용하여 함수 호출filter
통지됩니다makelist
makelist
가능한 모든 완료 목록을 반환합니다.grep
커서 아래 단어의 접두어를 커서까지 일치시켜 완성- 특이한 점은 바로
sort
이것 이다 - 다시 돌려줘
complete