grub: Shell-like scripting

 
 6.3 Writing full configuration files directly
 =============================================
 
 'grub.cfg' is written in GRUB's built-in scripting language, which has a
 syntax quite similar to that of GNU Bash and other Bourne shell
 derivatives.
 
 Words
 =====
 
 A "word" is a sequence of characters considered as a single unit by
 GRUB. Words are separated by "metacharacters", which are the following
 plus space, tab, and newline:
 
      { } | & $ ; < >
 
    Quoting may be used to include metacharacters in words; see below.
 
 Reserved words
 ==============
 
 Reserved words have a special meaning to GRUB. The following words are
 recognised as reserved when unquoted and either the first word of a
 simple command or the third word of a 'for' command:
 
      ! [[ ]] { }
      case do done elif else esac fi for function
      if in menuentry select then time until while
 
    Not all of these reserved words have a useful purpose yet; some are
 reserved for future expansion.
 
 Quoting
 =======
 
 Quoting is used to remove the special meaning of certain characters or
 words.  It can be used to treat metacharacters as part of a word, to
 prevent reserved words from being recognised as such, and to prevent
 variable expansion.
 
    There are three quoting mechanisms: the escape character, single
 quotes, and double quotes.
 
    A non-quoted backslash (\) is the "escape character".  It preserves
 the literal value of the next character that follows, with the exception
 of newline.
 
    Enclosing characters in single quotes preserves the literal value of
 each character within the quotes.  A single quote may not occur between
 single quotes, even when preceded by a backslash.
 
    Enclosing characters in double quotes preserves the literal value of
 all characters within the quotes, with the exception of '$' and '\'.
 The '$' character retains its special meaning within double quotes.  The
 backslash retains its special meaning only when followed by one of the
 following characters: '$', '"', '\', or newline.  A backslash-newline
 pair is treated as a line continuation (that is, it is removed from the
 input stream and effectively ignored(1) (⇒Shell-like
 scripting-Footnote-1)).  A double quote may be quoted within double
 quotes by preceding it with a backslash.
 
 Variable expansion
 ==================
 
 The '$' character introduces variable expansion.  The variable name to
 be expanded may be enclosed in braces, which are optional but serve to
 protect the variable to be expanded from characters immediately
 following it which could be interpreted as part of the name.
 
    Normal variable names begin with an alphabetic character, followed by
 zero or more alphanumeric characters.  These names refer to entries in
 the GRUB environment (⇒Environment).
 
    Positional variable names consist of one or more digits.  They
 represent parameters passed to function calls, with '$1' representing
 the first parameter, and so on.
 
    The special variable name '?' expands to the exit status of the most
 recently executed command.  When positional variable names are active,
 other special variable names '@', '*' and '#' are defined and they
 expand to all positional parameters with necessary quoting, positional
 parameters without any quoting, and positional parameter count
 respectively.
 
 Comments
 ========
 
 A word beginning with '#' causes that word and all remaining characters
 on that line to be ignored.
 
 Simple commands
 ===============
 
 A "simple command" is a sequence of words separated by spaces or tabs
 and terminated by a semicolon or a newline.  The first word specifies
 the command to be executed.  The remaining words are passed as arguments
 to the invoked command.
 
    The return value of a simple command is its exit status.  If the
 reserved word '!' precedes the command, then the return value is instead
 the logical negation of the command's exit status.
 
 Compound commands
 =================
 
 A "compound command" is one of the following:
 
 for NAME in WORD ...; do LIST; done
      The list of words following 'in' is expanded, generating a list of
      items.  The variable NAME is set to each element of this list in
      turn, and LIST is executed each time.  The return value is the exit
      status of the last command that executes.  If the expansion of the
      items following 'in' results in an empty list, no commands are
      executed, and the return status is 0.
 
 if LIST; then LIST; [elif LIST; then LIST;] ... [else LIST;] fi
      The 'if' LIST is executed.  If its exit status is zero, the 'then'
      LIST is executed.  Otherwise, each 'elif' LIST is executed in turn,
      and if its exit status is zero, the corresponding 'then' LIST is
      executed and the command completes.  Otherwise, the 'else' LIST is
      executed, if present.  The exit status is the exit status of the
      last command executed, or zero if no condition tested true.
 
 while COND; do LIST; done
 until COND; do LIST; done
      The 'while' command continuously executes the 'do' LIST as long as
      the last command in COND returns an exit status of zero.  The
      'until' command is identical to the 'while' command, except that
      the test is negated; the 'do' LIST is executed as long as the last
      command in COND returns a non-zero exit status.  The exit status of
      the 'while' and 'until' commands is the exit status of the last
      'do' LIST command executed, or zero if none was executed.
 
 function NAME { COMMAND; ... }
      This defines a function named NAME.  The "body" of the function is
      the list of commands within braces, each of which must be
      terminated with a semicolon or a newline.  This list of commands
      will be executed whenever NAME is specified as the name of a simple
      command.  Function definitions do not affect the exit status in
      '$?'.  When executed, the exit status of a function is the exit
      status of the last command executed in the body.
 
 menuentry TITLE ['--class=class' ...] ['--users=users'] ['--unrestricted'] ['--hotkey=key'] ['--id=id'] { COMMAND; ... }
      ⇒menuentry.
 
 Built-in Commands
 =================
 
 Some built-in commands are also provided by GRUB script to help script
 writers perform actions that are otherwise not possible.  For example,
 these include commands to jump out of a loop without fully completing
 it, etc.
 
 break ['n']
      Exit from within a 'for', 'while', or 'until' loop.  If 'n' is
      specified, break 'n' levels.  'n' must be greater than or equal to
      1.  If 'n' is greater than the number of enclosing loops, all
      enclosing loops are exited.  The return value is 0 unless 'n' is
      not greater than or equal to 1.
 
 continue ['n']
      Resume the next iteration of the enclosing 'for', 'while' or
      'until' loop.  If 'n' is specified, resume at the 'n'th enclosing
      loop.  'n' must be greater than or equal to 1.  If 'n' is greater
      than the number of enclosing loops, the last enclosing loop (the
      "top-level" loop) is resumed.  The return value is 0 unless 'n' is
      not greater than or equal to 1.
 
 return ['n']
      Causes a function to exit with the return value specified by 'n'.
      If 'n' is omitted, the return status is that of the last command
      executed in the function body.  If used outside a function the
      return status is false.
 
 setparams ['arg'] ...
      Replace positional parameters starting with '$1' with arguments to
      'setparams'.
 
 shift ['n']
      The positional parameters from 'n'+1 ... are renamed to '$1'....
      Parameters represented by the numbers '$#' down to '$#'-'n'+1 are
      unset.  'n' must be a non-negative number less than or equal to
      '$#'.  If 'n' is 0, no parameters are changed.  If 'n' is not
      given, it is assumed to be 1.  If 'n' is greater than '$#', the
      positional parameters are not changed.  The return status is
      greater than zero if 'n' is greater than '$#' or less than zero;
      otherwise 0.