Bug#702455: grub-common: wrong Bash auto complete for grub-set-default and grub-reboot
Alfredo Finelli
0x4146 at gmail.com
Wed Mar 6 19:28:00 UTC 2013
Package: grub-common
Version: 1.99-27
Severity: normal
Tags: patch
When using the commands "grub-set-default" and "grub-reboot" it is
possible, thanks to programmable completion, to let bash fill out the
command line with kernel names and boot options obtained from the entries
in "/boot/grub/grub.cfg". This completion is sometimes wrong.
Here is an example completion with errors. At the prompt I press <TAB>
after the command name:
# grub-set-default <TAB>
Linux, with Linux 3.2.0-4-amd64
Linux, with Linux 3.2.0-4-amd64 (recovery mode)
Linux, with Linux 3.8.2-t410
Linux, with Linux 3.8.2-t410 (recovery mode)
Grml Rescue System (grml64-small_2012.05.iso)
Network boot (iPXE)
In this case the correct title of grub menu entries with the Linux kernel
is "Debian GNU/Linux, with Linux ...", not what is shown above. For this
reason the following command line does not offer any completions:
# grub-set-default L<TAB>
If instead I try to complete starting with a "D", then I get the following:
# grub-set-default D<TAB>
# grub-set-default Debian\ GNU/Linux\,\ with\ Linux\ 3.
Linux, with Linux 3.2.0-4-amd64
Linux, with Linux 3.2.0-4-amd64 (recovery mode)
Linux, with Linux 3.8.2-t410
Linux, with Linux 3.8.2-t410 (recovery mode)
It offers the correct completion in the command line but still the wrong
list of suggestions.
The file "/etc/bash_completion.d/grub" is where auto completion functions
for grub are defined. By reading the source I discovered that the
completion specifications for the two commands contain the "-o filenames"
option. As you can read in the bash manual:
-o comp-option
The comp-option controls several aspects of the compspec's behavior
beyond the simple generation of completions. comp-option may be
one of: [...]
filenames
Tell readline that the compspec generates filenames, so it can
perform any filename-specific processing (like adding a slash
to directory names, quoting special characters, or suppressing
trailing spaces). Intended to be used with shell functions.
The two commands "grub-set-default" and "grub-reboot" do not expect a
filename as an argument, instead they work with a number or, in our case, a
menu item title. We want to auto complete a string that is not a filename.
The character "/" in the word "GNU/Linux" is the offending input because it
is wrongly considered a directory separator.
At first I tried to simply remove the "filenames" option from the
completion specifications, but then I faced a new problem: the user got
a correct list of suggestions but he also had to provide manually for
the correct quoting of the string to the shell.
# grub-set-default <TAB>
Debian GNU/Linux, with Linux 3.2.0-4-amd64
Debian GNU/Linux, with Linux 3.2.0-4-amd64 (recovery mode)
Debian GNU/Linux, with Linux 3.8.2-t410
Debian GNU/Linux, with Linux 3.8.2-t410 (recovery mode)
Grml Rescue System (grml64-small_2012.05.iso)
Network boot (iPXE)
# grub-set-default D<TAB>
# grub-set-default Debian GNU/Linux, with Linux 3.
The string that appears on the command line is unquoted and from there the
shell is not able to complete further; in this example it is trying to find
a completion for the word "3." and not for the full menu entry.
My solution to this problem was to change the way suggestion strings are
generated, so that they appear already quoted. Then you need just a
<TAB> key press to complete the common prefix and so on, with the same
functionality as with the wrong working "filenames" completion.
# grub-set-default <TAB>
# grub-set-default "
"Debian GNU/Linux, with Linux 3.2.0-4-amd64"
"Debian GNU/Linux, with Linux 3.2.0-4-amd64 (recovery mode)"
"Debian GNU/Linux, with Linux 3.8.2-t410"
"Debian GNU/Linux, with Linux 3.8.2-t410 (recovery mode)"
"Grml Rescue System (grml64-small_2012.05.iso)"
"Network boot (iPXE)"
# grub-set-default "D<TAB>
# grub-set-default "Debian GNU/Linux, with Linux 3.<TAB>
"Debian GNU/Linux, with Linux 3.2.0-4-amd64"
"Debian GNU/Linux, with Linux 3.2.0-4-amd64 (recovery mode)"
"Debian GNU/Linux, with Linux 3.8.2-t410"
"Debian GNU/Linux, with Linux 3.8.2-t410 (recovery mode)"
You can find my corrections to the code in the following patch.
Best regards.
--- /etc/bash_completion.d/grub 2013-03-06 11:00:39.676578999 +0100
+++ grub 2013-03-06 19:21:22.525938227 +0100
@@ -116,7 +116,7 @@
if [ -f "$config_file" ];then
local IFS=$'\n'
- COMPREPLY=( $(compgen \
+ COMPREPLY=( $(compgen -P \" -S \" \
-W "$( awk -F "[\"']" '/menuentry/ { print $2 }' $config_file )" \
-- "$cur" )) #'# Help emacs syntax highlighting
fi
@@ -167,12 +167,12 @@
__grub_set_default_program=$( echo grub-set-default | sed "s,x,x," )
have ${__grub_set_default_program} && \
- complete -F _grub_set_entry -o filenames ${__grub_set_default_program}
+ complete -F _grub_set_entry ${__grub_set_default_program}
unset __grub_set_default_program
__grub_reboot_program=$( echo grub-reboot | sed "s,x,x," )
have ${__grub_reboot_program} && \
- complete -F _grub_set_entry -o filenames ${__grub_reboot_program}
+ complete -F _grub_set_entry ${__grub_reboot_program}
unset __grub_reboot_program
-- System Information:
Debian Release: 7.0
APT prefers testing
APT policy: (900, 'testing'), (800, 'unstable')
Architecture: amd64 (x86_64)
Kernel: Linux 3.8.2-t410 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages grub-common depends on:
ii gettext-base 0.18.1.1-9
ii libc6 2.13-38
ii libdevmapper1.02.1 2:1.02.74-6
ii libfreetype6 2.4.9-1.1
ii libfuse2 2.9.0-2+deb7u1
ii zlib1g 1:1.2.7.dfsg-13
Versions of packages grub-common recommends:
pn os-prober <none>
Versions of packages grub-common suggests:
pn desktop-base <none>
pn grub-emu <none>
pn multiboot-doc <none>
ii xorriso 1.2.2-2
-- no debconf information
More information about the Pkg-grub-devel
mailing list