The way our bash completion string is that is gets user's input
and lets virsh completion code do all the work by calling 'virsh
complete -- $INPUT". The 'complete' command is a "secret",
unlisted command that exists solely for this purpose. After it
has done it's part, it prints candidates onto stdout, each
candidate on its own line, e.g. like this:
# virsh complete -- "net-u"
net-undefine
net-update
net-uuid
These strings are then stored into a bash array $A like this:
A=($($1 ${CMDLINE} complete -- "${INPUT[@]}" 2>/dev/null))
This array is then thrown back at bash completion to produce
desired output. So far so good. Except, when there is an option
with space. For instance:
# virsh complete -- start --domain ""
uefi\ duplicate
uefi
Bash interprets that as another array item because by default,
Internal Field Separator (IFS) = set of characters that bash uses
to split words at, is: space, TAB, newline. We don't want space
nor TAB. Therefore, we have to set $IFS when storing 'virsh
complete' output into the array.
Thanks to Peter who suggested it.
Resolves:
https://gitlab.com/libvirt/libvirt/-/issues/116
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tools/bash-completion/vsh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/bash-completion/vsh b/tools/bash-completion/vsh
index fb38e8616f..bbb25fc3eb 100644
--- a/tools/bash-completion/vsh
+++ b/tools/bash-completion/vsh
@@ -56,7 +56,7 @@ _vsh_complete()
# the name of the command whose arguments are being
# completed.
# Therefore, we might just run $1.
- A=($($1 ${CMDLINE} complete -- "${INPUT[@]}" 2>/dev/null))
+ IFS=$'\n' A=($($1 ${CMDLINE} complete -- "${INPUT[@]}"
2>/dev/null))
COMPREPLY=($(compgen -W "${A[*]%--}" -- ${cur}))
__ltrim_colon_completions "$cur"
--
2.26.2