環境変数があります$SCRIPT
。通常、オートコンプリートを使用できます
vim $SC<tab>
期待どおりに操作が完了します。一部のシステムでは機能しません。 bash完了がロードされましたが、この場合、完了はディレクトリ(cd $SCRIPT_DIREC<tab>
動作中)でのみ機能します。
主にbash 4.2に問題があります。
何がshopt
それを可能にすることができますか?
編集:私の設定を動作させるBash 4.3と動作しないBash 4.2(Ubuntu Server 12.04)と比較しましたshopt
。
答え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
1つの方法は、別名を次に設定することです。
alias Script="<Your $Script Here>"
ユーザーの .profile で/home/user/.profile
次のコマンドを使用してインポートします。
$ . profile
その後、自動的に完了することを確認します。