为什么Perl的系统返回值不是我所期望的?

2023-12-24

让我首先解释一下我想要实现的目标。本质上有两个 Perl 脚本。一种是我所说的带有 UI 的主脚本。运行此脚本的用户将看到他可以从菜单调用的其他脚本的列表。该列表是通过自定义配置文件加载的。主脚本的目的是能够在将来根据需要添加其他脚本,而无需更改源,并作为 cron 作业(非交互模式)和用户需要(交互模式)运行。根据公司政策,我无权发布整个脚本,因此我将发布交互模式用户选择部分:

for($i = 0;$i < @{$conf}+1;$i++)
    {
        if($i % 2 == 1 || $i == 0)
        {
            next;
        }
        print $n++ . ". @{$conf}[$i-1]\n";
    }
    print "(health_check) ";

    #
    # User selection
    #

    my $in = <>;
    chomp($in);

    if($in =~ /[A-Za-z]/)
    {
        write_log("[*] Invalid Selection: $in");
        print "\n<<<<<<<<<<<<>>>>>>>>>>>>>\n";
        print ">>> Invalid Selection <<<\n";
        print "<<<<<<<<<<<<>>>>>>>>>>>>>\n";
    }
    elsif($in == 0)
    {
        write_log("Exiting interactive mode");
        last;
    }
    elsif(scalar($scripts[$in]))
    {
        write_log("[*] running: $scripts[$in]");
        $rez = system('./' . "$scripts[$in]");

        if($rez == 0b00)
        {
            printf("%s: [OK]\n",$scripts[$in]);
        }
        elsif($rez == 0b01)
        {
            printf("%s: [WARNING]\n",$scripts[$in]);
        }
        elsif($rez == 0b11)
        {
            printf("%s: [NOT OK]\n",$scripts[$in]);
        }
        else
        {
            print "UNKOWN ERROR CODE: $rez\n";
        }
    }
    else
    {
        write_log("[*] Invalid Selection: $in");
        print "\n<<<<<<<<<<<<>>>>>>>>>>>>>\n";
        print ">>> Invalid Selection <<<\n";
        print "<<<<<<<<<<<<>>>>>>>>>>>>>\n";    
    }

    print "\n\nPress return/enter to continue...";
    <>;
}

write_log("Exiting interactive mode");

}

@{$conf} 是对可用脚本列表的引用。它包含脚本的名称和脚本的路径。

$i is used for looping.
$n is the script number which is used for the user to select which script to run.
$in is the user input in decimal value to select which script to run.
$scripts is the actual name of the script and not the path to the script.
$rez is the return code from the scripts.

这就是奇怪的地方。我有一个检查文件系统使用情况的脚本。一旦检查完毕,它将退出并提供适当的值供主脚本处理。

0 is Ok
1 is Warning
2 is Alert
3 is Warning + Alert

这是文件系统检查脚本的相关部分:

    if(check_hdd($warning_lvl, $alert_lvl))
{
    $return_val = $return_val | 0b01;
}

if(check_hdd($alert_lvl))
{
    $return_val = $return_val | 0b10;
}

exit $return_val;

如果有任何内容位于输入的两个参数范围之间,则 check_hdd 子例程将返回 1(例如,如果检测到文件系统使用百分比范围内的任何内容,第二个参数的默认值为 100%,则 check_hdd 子例程将返回 1 )。

所以这就是奇怪的地方......

例如,如果 hdd 脚本返回 1。主脚本将看到 256。

所以我进入了 hdd 脚本并强制它返回 256。

exit 256;

主脚本看到:0。所以我用不同的值做了这个并建立了一个小表。

HDD_Check Exit Value            Main is seeing Exit Value as
         1                                    256
         256                                    0
         257                                  256
         258                                  512
         259                                  768

啊。有趣的。让我们将其转换为二进制。

HDD_Check Exit Value (Base 2)       Main is seeing Exit Value as (Base 2)
         0b0000000001                             0b0100000000
         0b0100000000                             0b0000000000
         0b0100000001                             0b0100000000
         0b0100000010                             0b1000000000
         0b0100000011                             0b1100000000

诡异的。看起来它在传递值时执行以下操作:

return_value = return_value << 8

现在冗长的解释已经完成,有人有任何想法吗?我也尝试过这个die代替exit它也做同样的事情。出于某种原因,我觉得这是一些非常明显的东西,但我错过了......


这是定义的行为。

http://perldoc.perl.org/functions/system.html http://perldoc.perl.org/functions/system.html

返回值是退出状态 等待返回的程序 称呼。要获得实际的退出值, 右移八位(见下文)。

返回值-1表示启动程序失败或wait(2)系统调用出错(检查$!以了解原因)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么Perl的系统返回值不是我所期望的? 的相关文章

  • 多个与单个 Catalyst 应用程序

    我有多个作为 FCGI 运行的 Catalyst 应用程序 将它们整合为具有多个控制器的单个控制器是否有好处 Thanks Simone 内存 大概吧 我认为每台服务器至少要保留 15MB 左右 因此如果您在 3 台服务器上运行 3 个应用
  • CPAN shell 内存不足。在 Unix 上如何给它更多的内存?

    我得到一个Out of memory 所有安装的消息 我以前从未使用过 cpan 并且不太确定它是如何工作的 我做了一个ulimit在 cpan 目录中 结果是无限的 这是我正在看的内容 usr bin perl MCPAN e shell
  • Perl 中字符串之间的字符匹配计数

    我有一个字符串 例如字符串 1 需要与另一个字符串 字符串 2 匹配 两个字符串的长度相同并且不区分大小写 我想打印两个字符串之间的字符匹配数 E g String 1 stranger String 2 strangem Match co
  • 使用 Perl 分割大文本文件

    我必须将一个 1 8Tb 的大文本文件分成两部分 我只需要文件的后半部分 该文件有 n作为记录分隔符 I tried perl ne print if gt line to start from test txt gt result txt
  • 如何构建 Perl Web 服务基础设施

    我有许多用于管理多服务器基础设施的脚本 其中一些脚本需要 root 访问权限 一些需要访问数据库 并且大多数脚本都是基于 perl 的 我想将所有这些脚本转换为非常简单的 Web 服务 可以从不同的应用程序执行 这些 Web 服务将接受常规
  • 读入模板文件,使用用户输入填充并生成新文件

    我正在尝试读取如下所示的模板配置文件 template config path to speedseq package binary directory SPEEDSEQ BIN DIR usr local packages Sequenc
  • 如何在调试器模式下运行 perl 测试?

    我尝试在调试器下运行测试 perl d which prove t file t 但这没有任何效果 因为每个测试都是作为单独的作业运行的 我已经发现 exec选项 但是当我提供它时 我失去了任何选项 proverc文件和命令行 prove
  • 找不到 DBI.pm

    我正在尝试启动这个脚本 usr bin perl use DBI my dbh DBI gt connect dbi Oracle host lonlin2 sid TIMFX1AD port 1524 xbsesdbo xbsesdbo1
  • 由于 lpcap,CPAN 安装 Net::Pcap 和 Packet 模块失败

    最近 我尝试通过 cpan 安装 perl 模块 Net Packet 和 Net Pcap 但它抱怨找不到 pcap 库 所以我正在搜索 cpan 在安装模块时是否接受外部 lib include 目录 但到目前为止还没有运气 looki
  • 如何使用 Perl CGI 脚本提供图像?

    我的 Google fu 让我失望了 如何使用 Perl 提供已生成的图像 Example img src getimage pl getimage pl 里有什么 干得好 usr bin perl w my file inner nav
  • 在 Perl 中使用数据引用的正确方法

    我有一组想要处理的数据 为了简化我的代码 最好通过指向原始数据的引用数组来访问我的数据的某些子集 比解释更好的是 我写下了这个例子 它还没有工作 最后 我想更新原始数据 而不必更新所有子集 用 Perl 可以做这样的事情吗 usr bin
  • Perl:测试输入阅读器?

    有没有一种方法可以使用标准 Test 等模块自动测试 Perl 程序是否正在读取输入 例如标准输入正确吗 例如 测试一个从 STDIN 读取两个整数并打印它们之和的程序 这不是 100 清楚你的意思 我会回答假设你想编写一个测试脚本来测试你
  • Text::平衡和多行 xml

    看来我有点失落了 我需要解析一个大的 大约 100 mb 且相当难看的 xml 文件 如果我使用parsefile 它返回错误 文档元素后的垃圾 但它会很乐意解析文件的较小元素 所以我决定将文件分解为元素并解析它们 由于不鼓励使用正则表达式
  • 客户端浏览器关闭时服务器端 Perl CGI 脚本中断

    我已经尝试解决一个小问题很长一段时间了 但似乎我无法解决 我编写了一个 HTML 页面 它在提交表单时调用 perl CGI 脚本 该 CGI 在服务器端执行一定数量的任务 我让脚本将这些任务的步骤打印到 HTML 页面上的 iframe
  • 快速 Perl signint 处理程序

    收到 Ctrl C 时处理程序清理的最方便 最清晰的方法是什么 例如 当我的套接字服务器以这种方式被终止时 TCP 套接字永远不会关闭 我想要一个很好的衬里 我可以将其放在程序的顶部来设置 sigint 处理程序 或类似 atexit 的东
  • Perl 和 Selenium::远程::驱动程序

    再次编辑 我在弗吉尼亚州北部某处的 AWS 上有一台服务器 这是我的监控服务器 我从另一个状态 ssh 进入这个 Ubuntu 服务器来进行系统管理 我想在这台服务器上进行 Web 自动化测试 它将测试互联网上的 Web 应用程序 点击 U
  • 折叠具有多个字段的行

    我有这个代码 awk seen 1 2 a 1 a 1 a 1 t 2 END for i in a print i a i inputfile 我想折叠具有两个以上字段的行 但始终基于第一个字段作为索引 输入文件 三列制表符分隔 prot
  • 如何彻底删除 Perl 中的包?

    如何在 Perl 中彻底删除一个包 这不仅意味着包变量 还意味着 Perl 更新以处理继承更改和其他事情的任何魔术表 这个简单的测试 use warnings use strict use Test LeakTrace use Symbol
  • 如何在 PHP 中反序列化 Perl Data::Dumper 输出

    我在 Perl 中有一个导出变量的结果 如下字符串 VAR1 guard gt undef work hand gt undef images gt 1 gt mini height gt 150 width gt 150 extensio
  • 如何在 Perl 字符串中手动插入字符串转义符?

    在perl中假设我有一个像这样的字符串 hello tworld n 而我想要的是 hello world 也就是说 hello 然后是文字制表符 然后是 world 然后是文字换行符 或者等价地 hello tworld n 注意双引号

随机推荐