환경 변수가 있습니다 $SCRIPT
. 일반적으로 자동 완성을 사용할 수 있습니다
vim $SC<tab>
예상대로 작업이 완료됩니다. 일부 시스템에서는 작동하지 않습니다. bash 완료가 로드되었지만 이 경우 완료는 디렉터리( cd $SCRIPT_DIREC<tab>
작동 중)에서만 작동합니다.
주로 bash 4.2에 문제가 있습니다.
무엇이 shopt
그것을 가능하게 할 수 있나요?
편집: 내 설정을 작동하는 Bash 4.3 및 작동하지 않는 Bash 4.2(Ubuntu Server 12.04)와 비교했는데 shopt
차이점이 거의 없었고(주로 4.3 특정) 나머지는 동일하게 설정했지만 아무것도 작동하지 않았습니다.
답변1
특히 문제는 쉘 내장 명령이 <tab>
매개변수 이름을 확장할 수 있지만 외부 명령은 확장할 수 없다는 것입니다. 이것이 작동하는 이유는 다음과 같습니다 cd
. echo
및 read
기타 내장 기능은 OP가 예상한 대로 계속 작동합니다.
가게와는 아무 상관이 없습니다.
/etc/bash_completion
bash_completion 라이브러리( 내 12.04.4 시스템) 에 있습니다 . 버전 1.3에는 이러한 충돌 상황을 일으키는 요소가 있습니다. 1.99나 그 이전 어딘가에서 수정되었습니다.
bash_completion 라이브러리는 소스 코드가 있으면 자동으로 가져오므 ~/.bash_completion
로 다음 내용이 포함된 파일을 생성하여 12.04.4 라이브러리에서 작동하지 않는 함수 정의를 오버로드하는 것이 좋습니다. 나는 몇 가지 작은 테스트를 수행했지만 내가 사용한 기계는 이것의 영향을 받지 않았으므로 주의해야 합니다.
# following functions are direct copy/pastes from
# bash_completion RELEASE: 1.99
# overloading `_longopt()' and adding `_variables()' and `_init_completion()'
# appears to be all that is needed to correct this.
#
# http://unix.stackexchange.com/questions/126300/bash-autocomplete-variables-for-other-commands-than-cd
_init_completion()
{
local exclude= flag outx errx inx OPTIND=1
while getopts "n:e:o:i:s" flag "$@"; do
case $flag in
n) exclude+=$OPTARG ;;
e) errx=$OPTARG ;;
o) outx=$OPTARG ;;
i) inx=$OPTARG ;;
s) split=false ; exclude+== ;;
esac
done
# For some reason completion functions are not invoked at all by
# bash (at least as of 4.1.7) after the command line contains an
# ampersand so we don't get a chance to deal with redirections
# containing them, but if we did, hopefully the below would also
# do the right thing with them...
COMPREPLY=()
local redir="@(?([0-9])<|?([0-9&])>?(>)|>&)"
_get_comp_words_by_ref -n "$exclude<>&" cur prev words cword
# Complete variable names.
_variables && return 1
# Complete on files if current is a redirect possibly followed by a
# filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">".
if [[ $cur == $redir* || $prev == $redir ]]; then
local xspec
case $cur in
2'>'*) xspec=$errx ;;
*'>'*) xspec=$outx ;;
*'<'*) xspec=$inx ;;
*)
case $prev in
2'>'*) xspec=$errx ;;
*'>'*) xspec=$outx ;;
*'<'*) xspec=$inx ;;
esac
;;
esac
cur="${cur##$redir}"
_filedir $xspec
return 1
fi
# Remove all redirections so completions don't have to deal with them.
local i skip
for (( i=1; i < ${#words[@]}; )); do
if [[ ${words[i]} == $redir* ]]; then
# If "bare" redirect, remove also the next word (skip=2).
[[ ${words[i]} == $redir ]] && skip=2 || skip=1
words=( "${words[@]:0:i}" "${words[@]:i+skip}" )
[[ $i -le $cword ]] && cword=$(( cword - skip ))
else
i=$(( ++i ))
fi
done
[[ $cword -eq 0 ]] && return 1
prev=${words[cword-1]}
[[ ${split-} ]] && _split_longopt && split=true
return 0
}
_variables()
{
if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then
[[ $cur == *{* ]] && local suffix=} || local suffix=
COMPREPLY+=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \
"${BASH_REMATCH[2]}" ) )
return 0
fi
return 1
}
_longopt()
{
local cur prev words cword split
_init_completion -s || return
case "${prev,,}" in
--help|--usage|--version)
return 0
;;
--*dir*)
_filedir -d
return 0
;;
--*file*|--*path*)
_filedir
return 0
;;
--+([-a-z0-9_]))
local argtype=$( $1 --help 2>&1 | sed -ne \
"s|.*$prev\[\{0,1\}=[<[]\{0,1\}\([-A-Za-z0-9_]\{1,\}\).*|\1|p" )
case ${argtype,,} in
*dir*)
_filedir -d
return 0
;;
*file*|*path*)
_filedir
return 0
;;
esac
;;
esac
$split && return 0
if [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \
sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}=\{0,1\}\).*/\1/p' | sort -u )" \
-- "$cur" ) )
[[ $COMPREPLY == *= ]] && compopt -o nospace
elif [[ "$1" == @(mk|rm)dir ]]; then
_filedir -d
else
_filedir
fi
}
답변2
한 가지 방법은 별칭을 다음으로 설정하는 것입니다.
alias Script="<Your $Script Here>"
사용자의 .profile에서 /home/user/.profile
다음 명령을 사용하여 가져옵니다.
$ . profile
그런 다음 자동으로 완료되는지 확인하십시오.