#!/usr/bin/perl use strict; my $grub2_dir; my $grub2_reboot; my $show_mapped; my $id_name; my @menuentry; sub parse_menuentry { my ($parent, $menu) = @_; my @m = $menu =~ /(submenu|menuentry) \s+ '([^']*)' .*? ( \{ (?: [^{}]* | (?3))* \} )/sxg; for (my $i = 0; $i <= $#m; $i += 3) { my $type = $m[$i]; my $title = $m[$i+1]; my $data = $m[$i+2]; my $name = ($parent) ? "$parent>$title" : "$title"; if ($type eq "menuentry") { push @menuentry, $name; } elsif ($type eq "submenu") { &parse_menuentry ($name, $data); } } } $id_name = ""; if (@ARGV == 2 && ($ARGV[0] eq "--show-mapped")) { $show_mapped = 1; $id_name = $ARGV[1]; } elsif (@ARGV == 1) { $show_mapped = 0; $id_name = $ARGV[0]; } die "wrong command line options" if ($id_name eq ""); open(SYSCONF, ") { if (/LOADER_TYPE="(.*)"/) { my $bl = $1; if ($bl eq "grub2") { $grub2_dir = "/boot/grub2"; $grub2_reboot = "/usr/sbin/grub2-reboot"; } elsif ($bl eq "grub2-efi") { $grub2_dir = "/boot/grub2-efi"; $grub2_reboot = "/usr/sbin/grub2-efi-reboot"; } last; } } close (SYSCONF); die "no grub2_dir" if ($grub2_dir eq ""); open(MENU, "<$grub2_dir/grub.cfg") || die "no grub.cfg in $grub2_dir"; undef $/; while () { &parse_menuentry ("", $_); } close (MENU); my $ret = ""; my $name = ""; my $id = -1; if ($id_name =~ m!^[0-9]+$!) { if ($id_name < @menuentry) { $id = $id_name; $name = $menuentry[$id]; $ret = $name; } } else { my $i = -1; my $c = 0; $name = $id_name; foreach my $e (@menuentry) { if ($e =~ qr!\Q$name\E!) { $i = $c; last; } } continue { ++$c; } if ($i >= 0) { $id = $i; $name = $menuentry[$id]; $ret = "$id"; } } if ($show_mapped > 0) { print $ret; } else { system "$grub2_reboot \"$name\""; }