tools: Set IFS for bash completion script

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Michal Privoznik 2021-01-25 13:48:31 +01:00
parent aad2262b9e
commit b889594a70

View File

@ -56,7 +56,7 @@ _vsh_complete()
# the name of the command whose arguments are being # the name of the command whose arguments are being
# completed. # completed.
# Therefore, we might just run $1. # 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})) COMPREPLY=($(compgen -W "${A[*]%--}" -- ${cur}))
__ltrim_colon_completions "$cur" __ltrim_colon_completions "$cur"