少し背景情報です。この質問はこれに対するフォローアップです。Bashリモートオートコンプリート:「スタート」ディレクトリの変更
とにかく、私はカスタムオートコンプリートbashスクリプトを書いています。cd
特定のディレクトリ(必ずしも現在のディレクトリである必要はありません)から名前を取得したいことを除いて、オートコンプリート機能は以前と同じように機能したいと思います。ファイル名にスペースが含まれていない場合は正常に動作します。
簡単な例です。名前を取得するディレクトリに2つのファイルがあるとします。a_file
とanother file
(スペースに注意してください)。時には次のように進行します。
my_command
TABTAB
a_file
file
another
プレゼンテーションは完璧ではありませんanother file
。希望の出力は次のとおりです。また、スペースを自動的にエスケープしたいと思います。another
file
file_1
another file
my_command ano
TAB
my_command another\ file
私のスクリプトは次のとおりです
#!/bin/bash _get_file_list() { dir="/一部/パス/" CD $ディレクトリ *検索 - 最大深さ0 } _GetOptMyCommand() { 地域電流 完了=() 現在=${COMP_WORDS[COMP_CWORD]} ケース "$cur" -*) COMPREPLY=( $( compgen -W "-h -l --help --list --" -- "$cur" ) );; *) COMPREPLY=( $( compgen -W "$(_get_file_list)" -- "$cur" ) );; イサク 0を返す } フル -F _GetOptMyCommand my_command
ファイル名のスペースをどのように処理し、オートコンプリートスクリプトを次のように作成できますかcd
?
ベストアンサー1
この場合compgen
、これを使用する方が良いかもしれません。find
すでにシステム完了スクリプトがある可能性があります。たとえば、試してみてください。
locate bash_completion
Debian バリアントでは、次のようになります。
/usr/share/bash-completion/bash_completion
たとえば、どこで見つけることができますか_filedir
?最も簡単な方法は次のとおりです。
*)
pushd "/some/path" >/dev/null
_filedir
popd >/dev/null
これがオプションでない場合は、次のように開始する方法になります。
_comp_by_path()
{
local opt cur dir
local IFS=$'\n' x tmp
local -a tokens
opt="$1"
cur="$2"
dir="$3"
# Enter target directory
pushd "$dir" >/dev/null
# Get directories, filtered against current
[[ "$opt" != "-f" ]] && \
x=$( compgen -d -- "$cur" ) &&
while read -r tmp; do
tokens+=( "$tmp" )
done <<< "$x"
# Get files, filtered against current
[[ "$opt" != "-d" ]] && \
x=$( compgen -f -- "$cur" ) &&
while read -r tmp; do
tokens+=( "$tmp" )
done <<< "$x"
# If anything found
if [[ ${#tokens[@]} -ne 0 ]]; then
# Make sure escaping is OK
compopt -o filenames 2>/dev/null
COMPREPLY+=( "${tokens[@]}" )
fi
# Go back
popd >/dev/null
}
_GetOptMyCommand()
{
local cur
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "-h -l --help --list --" -- "$cur" ) );;
*)
_comp_by_path "any" "$cur" "/some/path"
esac
}
complete -F _GetOptMyCommand my_command
使用されるバリエーションはfind
次のとおりです。
_zaso()
{
local dir="$1"
pushd "$dir" >/dev/null
find * -maxdepth 0 2>/dev/null
popd >/dev/null
}
_comp_with_find()
{
local cur dir
local IFS=$'\n'
cur="$1"
dir="$2"
compopt -o filenames 2>/dev/null
COMPREPLY=( $( compgen -W "$(_zaso "$dir")" -- "$cur" ) );
}
また、printf
Bashにはオプションがあります%q
。したがって、引用符付き文字列を生成するには、次のオプションを使用できます。
find * -maxdepth 0 2>/dev/null && \
while read -r tmp; do
printf "%q\n" "$tmp"
done <<< "$x"
また、ファイル名に改行文字を含めることはできず、そのほとんどが破損する可能性があります。まだ\0
withを使用する方法が見つかりませんcompgen
。