当前位置: 首页 > news >正文

perl脚本中使用eval函数执行可能有异常的操作

perl脚本中有时候执行的操作可能会引发异常,为了直观的说明,这里举一个json反序列化的例子,脚本如下:

#! /usr/bin/perl
use v5.14;
use JSON;
use Data::Dumper;# 读取json字符串数据
my $json_str = join('', <DATA>);
# 反序列化操作
my $json = from_json($json_str);say to_json($json, { pretty => 1 });__DATA__
bad {"id" : 1024,"desc" : "hello world","other" : {"test_null" : null,"test_false" : false,"test_true" : true}
}

在这里插入图片描述

脚本中有意把正确json字符串之前加了几个字符,显然这个json字符串是不符合规范格式的,在git bash中执行这个脚本,结果如下:
在这里插入图片描述

下面用perl的eval函数改造这个脚本:

#! /usr/bin/perl
use v5.14;
use JSON;
use Data::Dumper;# 读取json字符串数据
my $json_str = join('', <DATA>);
# 反序列化操作
my $json = eval {return from_json($json_str);
};unless (defined $json) {say "from_json failed !!!!";
} else {say to_json($json, { pretty => 1 });
}__DATA__
bad {"id" : 1024,"desc" : "hello world","other" : {"test_null" : null,"test_false" : false,"test_true" : true}
}

脚本中用把from_json的操作放在eval函数中,输出结果如下:
在这里插入图片描述
显然,这个结果是可控的,可预期的。比如就可以使用这种方法判断json字符串是否合法,能够正常反序列化的就是合法的,否则就是非法的。eval函数的具体使用可以使用perldoc -f eval查看。

    eval EXPReval BLOCKeval    "eval" in all its forms is used to execute a little Perlprogram, trapping any errors encountered so they don't crash thecalling program.Plain "eval" with no argument is just "eval EXPR", where theexpression is understood to be contained in $_. Thus there areonly two real "eval" forms; the one with an EXPR is often called"string eval". In a string eval, the value of the expression(which is itself determined within scalar context) is firstparsed, and if there were no errors, executed as a block withinthe lexical context of the current Perl program. This form istypically used to delay parsing and subsequent execution of thetext of EXPR until run time. Note that the value is parsed everytime the "eval" executes.The other form is called "block eval". It is less general thanstring eval, but the code within the BLOCK is parsed only once(at the same time the code surrounding the "eval" itself wasparsed) and executed within the context of the current Perlprogram. This form is typically used to trap exceptions moreefficiently than the first, while also providing the benefit ofchecking the code within BLOCK at compile time. BLOCK is parsedand compiled just once. Since errors are trapped, it often isused to check if a given feature is available.In both forms, the value returned is the value of the lastexpression evaluated inside the mini-program; a return statementmay also be used, just as with subroutines. The expressionproviding the return value is evaluated in void, scalar, or listcontext, depending on the context of the "eval" itself. See"wantarray" for more on how the evaluation context can bedetermined.If there is a syntax error or runtime error, or a "die"statement is executed, "eval" returns "undef" in scalar context,or an empty list in list context, and $@ is set to the errormessage. (Prior to 5.16, a bug caused "undef" to be returned inlist context for syntax errors, but not for runtime errors.) Ifthere was no error, $@ is set to the empty string. A controlflow operator like "last" or "goto" can bypass the setting of$@. Beware that using "eval" neither silences Perl from printingwarnings to STDERR, nor does it stuff the text of warningmessages into $@. To do either of those, you have to use the$SIG{__WARN__} facility, or turn off warnings inside the BLOCKor EXPR using "no warnings 'all'". See "warn", perlvar, andwarnings.Note that, because "eval" traps otherwise-fatal errors, it isuseful for determining whether a particular feature (such as"socket" or "symlink") is implemented. It is also Perl'sexception-trapping mechanism, where the "die" operator is usedto raise exceptions.Before Perl 5.14, the assignment to $@ occurred beforerestoration of localized variables, which means that for yourcode to run on older versions, a temporary is required if youwant to mask some, but not all errors:# alter $@ on nefarious repugnancy only{my $e;{local $@; # protect existing $@eval { test_repugnancy() };# $@ =~ /nefarious/ and die $@; # Perl 5.14 and higher only$@ =~ /nefarious/ and $e = $@;}die $e if defined $e}There are some different considerations for each form:String evalSince the return value of EXPR is executed as a block withinthe lexical context of the current Perl program, any outerlexical variables are visible to it, and any packagevariable settings or subroutine and format definitionsremain afterwards.Under the "unicode_eval" featureIf this feature is enabled (which is the default under a"use 5.16" or higher declaration), EXPR is considered tobe in the same encoding as the surrounding program. Thusif "use utf8" is in effect, the string will be treatedas being UTF-8 encoded. Otherwise, the string isconsidered to be a sequence of independent bytes. Bytesthat correspond to ASCII-range code points will havetheir normal meanings for operators in the string. Thetreatment of the other bytes depends on if the"'unicode_strings"" feature is in effect.In a plain "eval" without an EXPR argument, being in"use utf8" or not is irrelevant; the UTF-8ness of $_itself determines the behavior.Any "use utf8" or "no utf8" declarations within thestring have no effect, and source filters are forbidden.("unicode_strings", however, can appear within thestring.) See also the "evalbytes" operator, which worksproperly with source filters.Variables defined outside the "eval" and used inside itretain their original UTF-8ness. Everything inside thestring follows the normal rules for a Perl program withthe given state of "use utf8".Outside the "unicode_eval" featureIn this case, the behavior is problematic and is not soeasily described. Here are two bugs that cannot easilybe fixed without breaking existing programs:*   It can lose track of whether something should beencoded as UTF-8 or not.*   Source filters activated within "eval" leak out intowhichever file scope is currently being compiled. Togive an example with the CPAN moduleSemi::Semicolons:BEGIN { eval "use Semi::Semicolons; # not filtered" }# filtered here!"evalbytes" fixes that to work the way one wouldexpect:use feature "evalbytes";BEGIN { evalbytes "use Semi::Semicolons; # filtered" }# not filteredProblems can arise if the string expands a scalar containinga floating point number. That scalar can expand to letters,such as "NaN" or "Infinity"; or, within the scope of a "uselocale", the decimal point character may be something otherthan a dot (such as a comma). None of these are likely toparse as you are likely expecting.You should be especially careful to remember what's beinglooked at when:eval $x;        # CASE 1eval "$x";      # CASE 2eval '$x';      # CASE 3eval { $x };    # CASE 4eval "\$$x++";  # CASE 5$$x++;          # CASE 6Cases 1 and 2 above behave identically: they run the codecontained in the variable $x. (Although case 2 hasmisleading double quotes making the reader wonder what elsemight be happening (nothing is).) Cases 3 and 4 likewisebehave in the same way: they run the code '$x', which doesnothing but return the value of $x. (Case 4 is preferred forpurely visual reasons, but it also has the advantage ofcompiling at compile-time instead of at run-time.) Case 5 isa place where normally you *would* like to use doublequotes, except that in this particular situation, you canjust use symbolic references instead, as in case 6.An "eval ''" executed within a subroutine defined in the"DB" package doesn't see the usual surrounding lexicalscope, but rather the scope of the first non-DB piece ofcode that called it. You don't normally need to worry aboutthis unless you are writing a Perl debugger.The final semicolon, if any, may be omitted from the valueof EXPR.Block evalIf the code to be executed doesn't vary, you may use theeval-BLOCK form to trap run-time errors without incurringthe penalty of recompiling each time. The error, if any, isstill returned in $@. Examples:# make divide-by-zero nonfataleval { $answer = $a / $b; }; warn $@ if $@;# same thing, but less efficienteval '$answer = $a / $b'; warn $@ if $@;# a compile-time erroreval { $answer = }; # WRONG# a run-time erroreval '$answer =';   # sets $@If you want to trap errors when loading an XS module, someproblems with the binary interface (such as Perl versionskew) may be fatal even with "eval" unless$ENV{PERL_DL_NONLAZY} is set. See perlrun.Using the "eval {}" form as an exception trap in librariesdoes have some issues. Due to the current arguably brokenstate of "__DIE__" hooks, you may wish not to trigger any"__DIE__" hooks that user code may have installed. You canuse the "local $SIG{__DIE__}" construct for this purpose, asthis example shows:# a private exception trap for divide-by-zeroeval { local $SIG{'__DIE__'}; $answer = $a / $b; };warn $@ if $@;This is especially significant, given that "__DIE__" hookscan call "die" again, which has the effect of changing theirerror messages:# __DIE__ hooks may modify error messages{local $SIG{'__DIE__'} =sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x };eval { die "foo lives here" };print $@ if $@;                # prints "bar lives here"}Because this promotes action at a distance, thiscounterintuitive behavior may be fixed in a future release."eval BLOCK" does *not* count as a loop, so the loop controlstatements "next", "last", or "redo" cannot be used to leaveor restart the block.The final semicolon, if any, may be omitted from within theBLOCK.

相关文章:

perl脚本中使用eval函数执行可能有异常的操作

perl脚本中有时候执行的操作可能会引发异常&#xff0c;为了直观的说明&#xff0c;这里举一个json反序列化的例子&#xff0c;脚本如下&#xff1a; #! /usr/bin/perl use v5.14; use JSON; use Data::Dumper;# 读取json字符串数据 my $json_str join(, <DATA>); # 反…...

『Redis』在Docker中快速部署Redis并进行数据持久化挂载

&#x1f4e3;读完这篇文章里你能收获到 在Docke中快速部署Redis如何将Redis的数据进行持久化 文章目录 一、拉取镜像二、创建挂载目录1 宿主机与容器挂载映射2 挂载命令执行 三、创建容器—运行Redis四、查看运行情况 一、拉取镜像 版本号根据需要自己选择&#xff0c;这里以…...

ubuntu创建apt-mirror本地仓库

首先创建apt-mirror的服务端&#xff0c;也就是存储所有apt-get下载的文件和依赖。大约需要300G&#xff0c;预留400G左右空间就可以开始了。 安装ubuntu省略&#xff0c;用的是ubuntu202204 ubuntu挂载硬盘&#xff08;不需要的可以跳过&#xff09;: #下载挂载工具 sudo apt…...

计算机网络 internet应用 (水

ARPA net ---Internet 前身 发展史: ARPA net 第一个主干网..美国军方NSFnet 美国国家科学基金会NSFANSnet 美国全国 (internet 叫法开始出现) 第二代互联网(现在() IP地址 IP地址 最高管理机构 - InterNIC IPV4 32位 IPV6 128位 域名 起名 解析 domain name sys…...

【ChatGLM3】第三代大语言模型多GPU部署指南

关于ChatGLM3 ChatGLM3是智谱AI与清华大学KEG实验室联合发布的新一代对话预训练模型。在第二代ChatGLM的基础之上&#xff0c; 更强大的基础模型&#xff1a; ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用了更多样的训练数据、更充分的训练步数和更合理的训练策略。在语义、…...

云原生Kubernetes系列 | Docker/Kubernetes的卷管理

云原生Kubernetes系列 | Docker/Kubernetes的卷管理 1. Docker卷管理2. Kubernetes卷管理2.1. 本地存储2.1.1. emptyDir2.1.2. hostPath2.2. 网络存储2.2.1. 使用NFS2.2.2. 使用ISCSI2.3. 持久化存储2.3.1. PV和PVC2.3.2. 访问模式2.3.3. 回收策略1. Docker卷管理...

Java实现快速排序算法

快速排序算法 &#xff08;1&#xff09;概念&#xff1a;快速排序是指通过一趟排序将要排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另外一部分的所有数据都要小&#xff0c;然后再按此方法对这两部分数据分别进行快速排序。整个排序过程可以递归进行&…...

MAC配置环境变量

1、配置 JAVA JDK 1.1、查看 JDK 安装目录 &#xff08;1&#xff09;可以在Android Studio中查看&#xff0c;复制该路径 &#xff08;2&#xff09;也可以在官网下载 Java JDK下载地址 mac中的安装地址是"资源库->Java->JavaVirtualMachines"中 1.2、…...

系列五、DQL

一、DQL 1.1、概述 DQL的英文全称为&#xff1a;Data Query Language&#xff0c;中文意思为&#xff1a;数据查询语言&#xff0c;用大白话讲就是查询数据。对于大多数系统来说&#xff0c;查询操作的频次是要远高于增删改的&#xff0c;当我们去访问企业官网、电商网站&…...

【智能家居】七、人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

一、翔云 人工智能开放平台 API文档开发示例下载 二、编译openSSL支持libcurl的https访问 安装SSL依赖库openSSL(使用工具wget)libcurl库重新配置&#xff0c;编译&#xff0c;安装运行&#xff08;运行需添加动态库为环境变量&#xff09; 三、编程实现人脸识别 四、Base6…...

基于node 安装express后端脚手架

1.首先创建文件件 2.在文件夹内打开终端 npm init 3.安装express: npm install -g express-generator注意的地方&#xff1a;这个时候安装特别慢,最后导致不成功 解决方法&#xff1a;npm config set registry http://registry.npm.taobao.org/ 4.依次执行 npm install -g ex…...

Mrdoc知识文档

MrDoc知识文档平台是一款基于Python开发的在线文档系统&#xff0c;适合作为个人和中小型团队的私有云文档、云笔记和知识管理工具&#xff0c;致力于成为优秀的私有化在线文档部署方案。我现在主要把markdown笔记放在上面&#xff0c;因为平时老是需要查询一些知识点&#xff…...

C语言中getchar函数

在 C 语言中&#xff0c;getchar() 是一个标准库函数&#xff0c;用于从标准输入&#xff08;通常是键盘&#xff09;读取单个字符。它的函数原型如下&#xff1a; int getchar(void);getchar() 函数的工作原理如下&#xff1a; 当调用 getchar() 函数时&#xff0c;它会等待…...

全栈开发组合

SpringBoot是什么&#xff1f; SpringBoot是一个基于Spring框架的开源框架&#xff0c;由Pivotal团队开发。它的设计目的是用来简化Spring应用的初始搭建以及开发过程。SpringBoot提供了丰富的Spring模块化支持&#xff0c;可以帮助开发者更轻松快捷地构建出企业级应用 Sprin…...

wpf TelerikUI使用DragDropManager

首先&#xff0c;我先创建事务对象ApplicationInfo&#xff0c;当暴露出一对属性当例子集合对于构成ListBoxes。这个类在例子中显示如下代码&#xff1a; public class ApplicationInfo { public Double Price { get; set; } public String IconPath { get; set; } public …...

Python+Appium自动化测试之元素等待方法与重新封装元素定位方法

在appium自动化测试脚本运行的过程中&#xff0c;因为网络不稳定、测试机或模拟器卡顿等原因&#xff0c;有时候会出现页面元素加载超时元素定位失败的情况&#xff0c;但实际这又不是bug&#xff0c;只是元素加载较慢&#xff0c;这个时候我们就会使用元素等待的方法来避免这种…...

详解Maven如何打包SpringBoot工程

目录 一、spring-boot-maven-plugin详解 1、添加spring-boot-maven-plugin插件到pom.xml 2、配置主类&#xff08;Main Class&#xff09; 3、配置打包的JAR文件名 4、包含或排除特定的资源文件 5、指定额外的依赖项 6、配置运行参数 7、自定义插件执行阶段 二、Maven打…...

PyQt6 QFrame分割线控件

锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计46条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话版…...

PostgreSql 序列

一、概述 在 PostgreSQL 中&#xff0c;序列用于生成唯一标识符&#xff0c;通常用于为表的主键列生成连续的唯一值。若目的仅是为表字段设置自增 id&#xff0c;可考虑序列类型来实现&#xff0c;可参考《PostgreSql 设置自增字段》 二、创建序列 2.1 语法 CREATE [ TEMPOR…...

【深度学习目标检测】六、基于深度学习的路标识别(python,目标检测,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...