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 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org