help-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Activating a configuration file within a submenu or a menuentry


From: Jordan Uggla
Subject: Re: Activating a configuration file within a submenu or a menuentry
Date: Sun, 8 Apr 2012 21:01:22 -0700

On Sun, Apr 8, 2012 at 2:58 PM, Arbiel Perlacremaz
<address@hidden> wrote:
> function other_cfg {
> insmod regexp
>
> for device in (*); do
> # il ne faut pas inclure dans le menu l\'amorçage actuel, pour éviter de
> tourner en rond
> # the present grub.cfg file is to be excluded from the menu, as to avoid
> looping on it
>    if [ "${device}/boot/grub" != "${prefix}" ]; then
>       if [ -e ${device}/boot/grub/grub.cfg ]; then
>        echo J\'ai trouvé ${device}/boot/grub/grub.cfg;
>         if probe --set=label --label "$device"; then
>            menuentry "$label" {
>                configfile  ${device}/boot/grub/grub.cfg
>            }

Here is your problem. The menuentry command does not act like a
closure, but rather more like a normal bash function; All variables in
grub-script are global; And commands in menu entries are by definition
executed after all of the commands in the script which created said
menu (Selecting a menu entry can be thought of as calling that
function, and the menu isn't displayed until your script finishes).
This means that when the menu entry is selected, $device will have the
value from the last iteration of the for loop, not from the iteration
of the for loop in which the menu entry was defined. Below is an
analogous bash script with the same incorrect assumption. If you can
understand why this bash script fails, you should understand why your
grub-script fails:

#!/bin/bash

for word in foo bar baz; do
  if [ "$word" = foo ]; then
    function print_foo {
      echo "$word"
    }
  fi

  if [ "$word" = bar ]; then
    function print_bar {
      echo "$word"
    }
  fi

  if [ "$word" = baz ]; then
    function print_baz {
      echo "$word"
    }
  fi
done

# Now that the for loop has defined the funtions (much like your for loop
# defined the menu entries) let's try calling these functions.

print_foo
print_bar
print_baz

# You might expect this to print "foo\n bar\n baz"
# but instead it prints "baz\n baz\n baz\n"
# End of example code

Grub menuentry commands can take arguments though, and these arguments
are available via positional parameters ($1 $2 etc). In fact they
always take at least one (which is used as the title of the menu
entry), where they differ from bash functions though is that these
arguments are given at the time the menu entry is defined, rather than
when it's selected or "called". The following example creates a menu
entry where the first positional is the title, "Fancy title", and
whose second positional parameter is the string "foo":

menuentry "Fancy title" foo {
  echo "The title of this menu entry is: $1"
  echo "The second positional parameter is $2"
  # Will print:
  # The title of this menu entry is: Fancy title
  # The second positional parameter is foo

  #sleep for 10 seconds so you can actually see the output
  sleep -v  --interruptible 10
}

# End example code

and what you probably want is a menu entry like this:

menuentry "Boot $label" "$device"{
  device="$2"
  configfile  "${device}/boot/grub/grub.cfg"
}

-- 
Jordan Uggla (Jordan_U on irc.freenode.net)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]