perl 脚本在 do-while 语句的第一个 运行 之后不打印

perl script does not print after first run of do-while statement

我正在尝试使用 Perl 为服务器中的简单菜单制作脚本,该菜单具有从 1 到 3 的三个选项,如果您输入任何其他数字,它应该会提示您输入从 1 到 1 的数字3、代码如下:

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();

在测试此脚本时,如果用户输入大于 3 或小于 1 的数字,则会提示错误消息,但如果稍后输入任何输入值,脚本就会结束,这是我所做的测试:

您的问题是当您将重试函数放在 if-clause 中时,您的循环控制和打印语句分开了。然后执行将从第一个 if-clause 继续执行,跳过所有其他 elsif 并直接跳到最后,它将满足 until 并退出。

您还尝试在单引号字符串中使用 \n。那行不通,您需要一个双引号字符串。

你需要的是只有一个读取语句,当读取失败时重试整个循环。像这样

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();

注意 no warnings 'numeric' 添加。此代码依赖于您 运行 关闭警告,否则您会收到有关数值比较的警告:

Argument "asd" isn't numeric in numeric eq (==) at ...

修复它的一种方法是清理输入并强制它为数字,即使它不是。例如

$action =~ s/\D+//g;          # remove non-numbers
$action = 0 unless $action;   # if "" turn it into 0

或者您可以忽略这些警告

no warnings 'numeric';