当前位置: 首页 > 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;提高了检测速度和准确性。…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...

电脑桌面太单调,用Python写一个桌面小宠物应用。

下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡&#xff0c;可以响应鼠标点击&#xff0c;并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...