I am trying to make an script for a simple menu in a server using Perl, this menu has three options ranging from 1 to 3 and if you input any other number it should prompt you to input a number fron 1 to 3. The code is as folows:
sub main_menu ()
{
system('clear');
print ('########## BIENVENIDOS A TERMINAL SERVER DE GOSIT ##########\n\n\n\n\n
Seleccione una accion:\n\n
1) Administracion de dispositivos\n
2) Gestion de backups\n
3) Salir del Terminal Server\n\n\n
Ingrese opcion: ');
$action = <>;
do
{
if ($action < '1' || $action > '3')
{
print (" Por favor seleccione una opcion valida: ");
$action = <>;
print ("\n\n");
}
elsif ($action == '1')
{
#admin_menu();
print ("to admin menu\n");
}
elsif ($action == '2')
{
#backup_menu();
print ("to backup menu\n");
}
elsif ($action == '3')
{
print ("Saliendo de TERMINAL SERVER\n\n");
exit
}
} until ($action == '1' || $action == '2' ||$action == '3' );
}
main_menu();
While testing this script if the user inputs a number greater than 3 or lower than 1 the error message is prompted but if later any input value is enterd the script ends, here are the tests I made:
CodePudding user response:
Your problem is that your loop control and print statements separate when you put the retry function inside the if-clause. Then execution will continue from the first if-clause, skip over all the other elsif
s and skip right to the end, where it will satisfy the until
and exit.
You also try to use \n
inside a single quoted string. That will not work, you need a double quoted string.
What you need is to have just one read statement, and just retry the whole loop when the read fails. Like this
use strict;
use warnings;
sub main_menu {
while (1) { # loop can only be exited manually
system('clear');
print '########## BIENVENIDOS A TERMINAL SERVER DE GOSIT ##########\n\n\n\n\n
Seleccione una accion:\n\n
1) Administracion de dispositivos\n
2) Gestion de backups\n
3) Salir del Terminal Server\n\n\n
Ingrese opcion: ';
my $action = <>;
no warnings 'numeric'; # disable numeric warnings
if ($action == 1) {
print ("to admin menu\n");
} elsif ($action == 2) {
print ("to backup menu\n");
} elsif ($action == 3) {
print ("Saliendo de TERMINAL SERVER\n\n");
exit
} else {
print (" Por favor seleccione una opcion valida.\n");
}
print "Press any key to continue..."; # needed to be able to read message
<>; # for pausing the screen
};
}
main_menu();
Note the no warnings 'numeric'
addition. This code relies on you running it with warnings off, or else you get warnings about numerical comparisons:
Argument "asd" isn't numeric in numeric eq (==) at ...
One way to fix it is to clean up the input and force it to be numerical, even when it is not. E.g.
$action =~ s/\D //g; # remove non-numbers
$action = 0 unless $action; # if "" turn it into 0
Or you can just ignore those warnings
no warnings 'numeric';