perl – 虫虫之家 http://ijz.me 略懂技术 Sat, 01 Mar 2025 15:30:19 +0000 zh-Hans hourly 1 https://wordpress.org/?v=6.7.2 Perl 6发布新版本Rakudo Star 2018.01 http://ijz.me/?p=998 http://ijz.me/?p=998#respond Thu, 01 Feb 2018 00:58:00 +0000 http://ijz.me/?p=998 1月29日,Rakudo和Perl 6开发组在官方博客 http://rakudo.org/ 发布消息,宣布Rakudo Star 2018.01生产版本正式发布。其源码包已经可下载,
下载地址:https://rakudo.perl6.org/downloads/star/
Windows 二进制安装包,MAC 二进制安装包稍后会在同一地址提供下载。
这是继 Perl 6 圣诞版本 v6.c 版本后,又一个生产版本,支持官方 MoarVM 虚拟机向后全功能兼容(对支持平台所有模块的测试都通过)。


目前 Perl 6 版本发布周期是季度性发布。
需要提及的是,本次发布的 Rakudo Star 版本不能完全向后兼容 JVM 所有功能,只能完全向后兼容 MoarVM。
本地发行包 —— 包括 2018.01 版本的 Rakudo Perl 6 编译器,MoarVM 虚拟机及核心模块、文档以及 Perl 6 社区收集的其他资源。
Rakudo 编译器的更新列表,详见安装包 rakudo/docs/announce 目录下的 2017.10、2017.11.md、2017.12.md、2018.01.md 文档里。

额外科普:
Perl 6 仅仅指语言,Rakudo Star 是官方的 Perl 发行版本,包括编译器、虚拟机和核心功能模块。当然 Perl 6 还有其他官方和第三方的 Perl 6 发行版版本,比如大家都熟悉的春哥的 fanlang 语言就是运行在 Openresty 上的Perl 6 “方言“。
MoarVM 是官方的 Perl 6 虚拟机,Perl 的虚拟机还支持 Java 虚拟机的 JVM,用于在 JVM 上跑 Perl 6。
Perl 6 文档中文化 —— 笔者在 github 上创建了一个官方文档 Perl 6 doc 中文化项目,欢迎有志的同学一起加入,完善和推广。


码云的托管地址为:https://gitee.com/ijz/perl6doc

]]>
http://ijz.me/?feed=rss2&p=998 0
打印特定行范围的多种方法(5-10行) http://ijz.me/?p=985 http://ijz.me/?p=985#respond Thu, 07 Sep 2017 12:31:00 +0000 http://ijz.me/?p=985 废话少说,直接撸代码:

perl -ne 'print if 5..10' xxoo #感谢flw提醒,忘记这个了
perl -ne 'print if $.>=5 and $.<=10' xxoo
perl -ne 'print if int($.) ~~ (5..10)'
perl -ne 'print if grep { $_ == $. } 5..10'xxoo
sed -ne '5,10 p' xxoo
awk 'NR==5,NR==10' xxoo
head -10 xxoo |tail -6
tail -n +5 xxoo | head -n 6
grep . -n xxoo |grep -E "^(5|6|7|8|9|10):"|perl -lpe 's/\d+://'

]]>
http://ijz.me/?feed=rss2&p=985 0
关于perl6的若干问题?(Perl6.d版本将会在2018年推出) http://ijz.me/?p=983 http://ijz.me/?p=983#respond Fri, 23 Jun 2017 12:20:00 +0000 http://ijz.me/?p=983

17年磨一剑,在perl人艰苦卓绝的努力下,perl 6终于在2015年圣诞节推出了正式版本V6.c版本(c代表圣诞节)。 期间几度波折,发生了很多很的事情。最令人津津乐道的一条是Perl6 最先成型的pogs版本主程台湾大牛唐宗汉易性为唐凤,另IT界叹为观止,广泛流传。

20年积累了宇宙巨能的perl6究竟有啥黑科技?本文借自perl6官方的faq,翻译成中文,以帮助我们揭开perl6的潘多拉宝盒。

笔者计划一项目perl6doc中文化的项目,这篇文章为perl6doc中文化的第一个成果,如果有什么纰漏和错误,请帮助我指出 。另外有志于学习perl6和参与项目的同仁也大大的欢迎哦。

项目的地址为:http://git.oschina.net/ijz/perl6doc

最新更新是Perl6.d版本将会在2018年推出,让我们期待把!

FAQ perl6最常问到的问题

一般性问题

Rakudo和Perl 6 有啥区别?

正确的说法是, Rakudo 是perl6的的实现。它是目前最完全的实现版本,目前还存在其他几个实现,将来也许 会有更多的实现。Perl 6是语言的定义。目前来讲,Perl 6和Rakudo名称可以通用。

第一个perl版本是6.0.0?

NO,perl 6 第一个正式发布版是v6.c(c代笔Christmas圣诞节)。 接下来发布的版本是带点版本(比如,v6.3.2),或者大版本的话(v6.d)

运行perl6 -v会输出编译器版本号:

$ perl6 –v

输出”This is Rakudo version 2017.07 built on MoarVM version 2017.07 implementing Perl 6.c“。

Perl v6.d 大概什么时候发布?

2018年内某时间点。这是实现6.d特性的第一个版本,具体日期后面会发布。 实际上通过使用use v6.d.PREVIEW我们已经在6.c的编译支持了很多6.d的新特性 pragma

perl6开始之旅,我应该安装什么?

Mac用可安装Rakudo Star DMG包,下载地址: http://rakudo.org/downloads/star

Windows用户可以通过Rakudo Star MSI安装. 你必须事先安装Windows Git和Strawberry Perl5 然后用zef包管理软件安装perl6模块。

Linux用户直接下载Rakudo Star http://www.perl6.org/downloads/ ,然后编译安装.

Linux和Mac用户也可以通过操作系统发行方或者第三方的二进制包安装,发行方包可能版本会老一点.

我们也提供Rakudo Star docker容器的镜像,地址为 https://hub.docker.com/_/rakudo-star/

对于perl老司机我对 Rakudo的开发感兴趣,有啥好的建议?

X<|rakudobrew (FAQ)>

最简便的方法是clone仓库the repository并且对其编译 从源码编译文档

部分人也可以选择rakudobrew这允许我们安装多版本 rakudo,从中选择自己喜欢的版本。请先浏览文档 rakudobrew 这个工具相当于perl5的perlbrew或者python,ruby的相应的多版本管理工具。

上哪里找Perl6的文档?

请浏览官方文档站(特别是他的“Language”部分。 还有资源页)。 你可以通过在线perl6频道寻求帮助 或者通过谷歌搜索聊天记录

Perl6 specification是什么?

Perl6 specification是指perl6 官方的测试套件.我们称它为roast,其地址为 hosted on github. 任何编译测试通过的就会加入到Perl 6 specification。

Roast的主分支对应最新的开发版本,它仍未划入任何的specification。其他分支则对应于不同的specific版本。 例如,”6c.errata”。

有Perl6相关主题的字汇表么?

是的, 其链接为glossary.

作为一个perl程序员,我想知道Perl5和Perl6的不同点是啥?

本文档的Language部分,有几个5to6-的指导教程。 其中最主要的是5to6-nutshell guide

我是一位Ruby程序,我该怎么快速入门perl6?

请浏览’rb-nutshell’文档,链接为https://docs.perl6.org/language/rb-nutshell

模块

Perl6有没有CPAN?

有,和Per5的CPAN一样,CPAN已经完全支持Perl6。唯一的区别是用PAUSE 升级模块时候,你必须选择Perl 6为目标目录。App::Mi6工具 模块可用于,简化这个更新流程。最新版本的zef模块安装 自动的检查CPAN上最新版本的模块,以及GitHub-based ecosystem

我能在Perl6中使用perl模块么?

没问题,通过 Inline::Perl5可以很好的运行大多数的perl5模块,甚至 包括Catalyst和DBI.

我能在Perl6中执行c和c++么?

Nativecall使这工作变的非常简单.

Nativecall不能找到libfoo.so,我的系统中只有libfoo.so.1.2!

这是Debian系linux运行Nativecall常见的问题.你需要安装C包,并对缺失的问题设置符号链接。

那些传统的UNIX库函数如何调用?

利用Nativecall调用它们非常简单。同时还有一个生态系统模块POSIX也可用.

Rakudo有核心的标准库么?

Rakudo Star发行包携带很多有用的了 模块。 Rakudo编译器发布仅仅包括一些最常用的基本模块。 更多的模块在ecosystem

有没有类似B::Deparse的模块?我如何处理AST?

使用--target=optimize命令行选项来预览程序中的AST。例如: perl6 --target=optimize -e 'say "hi"'。 静态优化后,optimize赋给AST处理目标,同时目标 ast给予AST前面的步骤。 可通过运行perl6 --stagestats -e ""得到所有可用目标的列表。

语言特性

我怎么样能dump出Perl6的数据结构 (和perl5的Data::Dumper一样有类似的模块么?)

典型地是使用say例程,对”gist” 对象的dump使用gist方法。更多细节可以通过 perl方法,这通常会返回 EVAL样式的代码表示。

如果使用是rakudo implementation,你可以使用其特有的 non-standard dd routine例程来dump 他的输出与perl类似,包含更多多的信息。例如:

my $foo = { foo =&gt; ‘bar’ };

say $foo.perl;# 输出: «${:foo(“bar”)}␤»

say $foo;# 输出: «{foo =&gt; bar}␤»

# 在rakudo实现中,支持非标准的例程

dd $foo;# 输出: «Hash $foo = ${:foo(“bar”)}␤»

同时perl6生态系统也有几个专门的模块提供更完善 的数据结构dump,包括支持带彩色的输出等。

Perl6命令行(REPL)下我如何得到输入命令的历史?

请安装Linenoise 模块.

对Unix系的操作系统另外还有一个方法就是使用rlwrap。在debian系操作系统可以通过 运行以下命令安装。

for code :lang&lt;shell&gt;

sudo apt–get install rlwrap

为什么Rakudo编译这样报错?

如果 当前输出是编译时错误,否则是运行时错误。

例如:

=begin code :skip–testsay 1/0;# 试图对0整除sub foo( Int $a, Int $b ) {…}foo(1)# ===抱歉!=== 编译时报错 …=end code
1234567=begin code :skip–testsay 1/0;# 试图对0整除sub foo( Int $a, Int $b ) {…}foo(1)# ===抱歉!=== 编译时报错 …=end code

(Any) 是啥?

Any是最高层的基类,其它绝大多数类都继承它。Any类型对象最为变量和参数 未明确指类型时候的默认值 这意味着当你答应一个没有任何值gist变量时候会输出(Any)。比如使用say routine:

1234567891011=begin codemy $foo;say $foo; # 输出: «(Any)␤»my Int $baz;say $baz; # 输出: «(Int)␤»my $bar = 70;say $bar; # 输出: «70␤»=end code

为了测试一个变量是否具有定义的值,使用L和L例程。其他几个测试定义与否结构有: withorwith,以及without语句, [<//>(/routine/$SOLIDUS$SOLIDUS),andthennotandthen,以及orelse操作符。还有 type constraint smileys

so是什么?

so是一个弱优先级操作符,强制为Bool。 它和? 前缀操作符具有相同语义,类似于and和低优先级的&&

实例:

12say so 1|2 == 2;# 输出: «True␤»

本例中的,比较的结果(是一个 Junction),被转化为布尔型打印。

:D 和 :U 修饰的意义?

在perl6中,类和其他类型都是对象,并且只能通过其自己类型的类型检查。

例如,如果你定义一个变量

12my Int $x = 42;

然后你不仅可以给他赋值整数(那就是,类实例Int),还有Int 类型对象自己。

如果你要排除类型对象,你可以附加:D 类型笑脸,他带包已”定义”.

1234567=begin code :skip–testmy Int:D $x = 42;$x = Int;# 异常退出:# 给$x赋值是类型检查错误;# 期待 Int:D 但是赋值的是Int=end code

类似的,C<:U> 限制为未定义的值,也就是说,类型对象。如果你限制既不能为类型对象 也不能为实例,你可以用C<:_>.

修饰符 --> 有啥作用?

L«–>|/type/Signature#Constraining_Return_Types» 为限制返回为一个类型或者一个定义的值.

例子,限制为一个类型:

123456789=begin code :skip–testsub divide–to–int( Int $a, Int $b —&gt; Int ) {return ($a / $b).narrow;}divide–to–int(3, 2)#  返回值类型检查失败期待Int但是返回Rat=end code

例子,限制为一个定义的返回值:

1234sub discard–random–number( —&gt; 42 ) { rand }say discard–random–number;# 输出: «42␤»

在本例中,由于返回值已经定义,所以最终值被抛弃。

我怎么从Junction抽取一个值?

如果你想从Junction中,抽取值,你可能做错了,你需要的应该是 Set

Junctions表示匹配的意思,不用来做操作的。如果你费用坚持这样做,你可以滥用自动线程:

123456789sub eigenstates(Mu $j) {my @states;–&gt; Any $s { @states.push: $s }.($j);@states;}say eigenstates(1|2|3).join(‘, ‘);# 打印出 1, 2, 3 或者一个置换方法。

如果Str为不可改变, s/// 如何工作? $i++ 如何工作?

perl6中,许多基本类型的值都是不可改变的,但是存放他们的变量却不是,C<s///> 操作符是对 变量的操作,操作是会生成一个新的字符串对象。同样,C<$i++>也是工作C<$i>变量上,并不是对 值本身的操作。

知道这点后,我们一般就不会试图去修改一个字符串(比如'hello' ~~ s/h/H/) 但是可能不经意间使用 map做了这样事情:

12345678my @foo = &lt;hello world&gt;.map: { s/h/H/ } ; # 抛出异常,# “Cannot modify an immutable Str (hello)”my @bar = &lt;hello world&gt;».subst–mutate: ‘h’, ‘H’; # 抛出异常,# “Cannot resolve caller subst-mutate(Str: Str, Str);# the following candidates match the type but require# mutable arguments: …”

实际上,要做的不是修改原始值,而是返回一个新的值得操作

123my @foo = &lt;hello world&gt;.map: { S/h/H/ };# [‘Hello’,’world’]my @bar = &lt;hello world&gt;».subst: ‘h’, ‘H’; # [‘Hello’,’world’]

更多信息,可以浏览 containers

数组引用和自动解引用是怎么回事?需要@前缀么?

在perl6中,一切皆引用,所以专门谈论引用意义不大。不像perl5,标量变量也能直接包含数组:

12345678my @a = 1, 2, 3;say @a;# 输出: «[1 2 3]␤»say @a.^name;# 输出: «(Array)␤»my $scalar = @a;say $scalar;# 输出: «[1 2 3]␤»say $scalar.^name;# 输出: «(Array)␤»

最大的不同是插入标量中的数组当为列表上下文的一个值,而数组则会循环迭代。

1234567891011121314=begin code :skip–testmy @a = 1, 2, 3;my $s = @a;for @a { … }# 循环3次for $s { … }# 只会循环一次my @flat = flat @a, @a;say @flat.elems;# 输出: «6␤»my @nested = flat $s, $s;say @nested.elems;# 输出: «2␤»=end code

你可以用@( ... ) 或者 用表达式的.list方法,强制展开,或者为成员上下文(不能展开)

为什么要用sigil? 不能没有他们么?

有几个原因:

  • 便于解释变量为字符串
  • 给不同种类的变量和twigils隔离为微命名空间,避免命名冲突
  • 可以便捷地区分单复数
  • 就像自然语言中的强制性动名词标记,是大脑最直白处理的方式
  • 但他也不是强制的,你也可以自定义sigil(如果你介意引起歧义的话)

Str类型不支持关联索引?

你可能是想混用字符解释器和HTML

12345=begin code :skip–testmy $foo = “abc”;say “$foo&lt;html-tag&gt;”;=end code

perl6认为$foo为一个哈希,而C«<html-tag>»会被当成字符哈希键。我们用一个 大括号来加深理解:

123my $foo = “abc”;say “{$foo}&lt;html-tag&gt;”;

perl6中有协程么? yield呢?

perl6没有像python一样的yield语句,但是它通过懒列表提供类似地函数式功能。 有两种普遍的方法写协程,返回懒列表

12345678910111213=begin code :skip–test# 第一种方法, gather/takemy @values = gather while have_data() {# do some computationstake some_data();# do more computations}# 第二种方法, 对一个懒列表使用.map或者类似的方法my @squares = (1..*).map(–&gt; \x { x² });=end code

为什么我不能从new方法初始一个私有属性,我该怎么操作?

诸如下面代码:

12345678class A {has $!x;method show–x {say $!x;}}A.new(x =&gt; 5).show–x;

输出不为5。私有属性是_private_,这意味着对外不可见。如果默认构造函数可以初始化他们的话, 他们就可能暴露在公共API.

如果你坚持要这样做,可以增加一个submethod BUILD来初始化他们:

123456789class B {has $!x;submethod BUILD(:$!x) { }method show–x {say $!x;}}B.new(x =&gt; 5).show–x;

BUILD会被默认的构造函数调用(间接地,查看 Object Construction了解更多),构造函数调用 所有用户传递过来的命名的参数。:$!x 是命名为x的命名参数,当带 x命名参数被调用 时,他的值会被绑定到属性 $!x

如果不这样做。如果名称是公有的,这样定义$.x也是没有害处。因为默认外部视图是只读的, 你仍然只能通过内部地 $!x操作它。

sayput 和 print 有啥区别?

最明显地差异是 say和 put输出会自带换行符,但是print没有。

其他的不同时:printput通过调用Str方法把所有参数项会当成一个字符串,say则 是用 gist方法。前者适合机器,后者更人性化。

或者完全的不同,$obj.Str 给出一个字符表达,$obj.gist给出一个简单对象总结,适合开发人员 辨别。 $obj.perl会给出一个perl式的表达。

例如:类型对象,也叫做“未定义值”,字符化结果为一个空串,并且给予警告。而gist方法会返回 类型的名称,紧跟着一个空括弧(表示除了类型外没有任何值)。

my Date $x;# $x包含一个Date类型对象
print $x;# 输出为空和警告
say $x;# 输出: «(Date)␤»

所以,say更适合做调试;显示是人优化过的; printput更适合给其他应用输出结果。

put是介于printsay之间的调和。和print一样适合为其他程序输出结果,同时也像 say一样输出结果自带换行。 and like say, it adds a newline at the end of the output.

tokenrule有何不同 ?

<regex>,tokenrule 都用于引入正则表达式,但是语法上略有不同。

token意味着:ratchet或者:r修饰符,这会防止规则被回溯。

rule 表示:ratchet:sigspace(简写为:s)修饰符,意味着规则不可以回溯,并且将 正则表达式中空白符号作为 C«<.ws>» 调用(不捕获)(例如,可以用来匹配空格,除了两单词之间的空格)。 正则表达式开头和每个可选分支|的开头空白会被忽略。

regex 定义一个没有任何暗示修饰符的纯正则.

diefail有啥不同?

die抛出一个异常.

fail 返回一个Failure对象.(如果在词法范围内调用定义过 use fatal;),fail抛出一个异常 而不是返回)。

Failure是一个非抛出或者“懒”异常。它一个包含了异常的对象,如果你想用 Failure作为普通对象 抛出一个异常。或者在sink上下文中忽略它。

Failuredefined检查中返回False,你可以用 exception方法抽取异常。

为什么wantarraywant 不见了? 我怎么才能不同上下文中返回不同的类型?

perl5用wantarray函数来测试调用的对象是void, scalar或者列表。perl6没有这样的结构,因为在perl6中上下文不再是关键;例如, 一个例程不需要知道哪个上下文被调用了,因为上下文是惰性的(只有在最后结果被使用时候才会知道)。

例如,perl6有多调度器,所以,下面的代码:

=begin code :skip–test
multi w(Int $x) { say ‘Int’ }
multi w(Str $x) { say ‘Str’ }
w(f());
=end code

没有办法知道调用的 sub f需要一个字符串或者整数,由于它自己现在也不知道会调用啥 一般来讲,这需要解决halting问题,对perl编译器作者也是个头疼的问题。

实现perl6上下文敏感的一个方法是返回一个对象。它知道如何响应上下文中典型的方法调用。 在perl6中,相比较它听起来,这实际上是一个lot easier, 和其他语言的其他特性,既可以减轻首先需要的并且最大可能是覆盖到wantarray的用例。

例如,regex匹配返回匹配对象,知道如何影响列表索引,哈希索引。并且可以变成匹配字符串

PointerOpaquePointer有什么不同?

OpaquePointer已经过时,被Pointer取代了.

Perl6实现

那种perl6实现可用的?

目前,开发最完善是Rakudo(支持多虚拟机后端)。曾经的实现包括Niecza (.NET)和 Pugs (Haskell)。 其他客用的实现请浏览Perl 6 Compilers

Rakudo使用什么语言开发的?

我们可以最直接告诉你Rakudo基本上都是用perl6开发的。说的细一点的话,Rakudo使用perl和 NQP (“Not Quite Perl”)混合开发的。NQP是一个轻量地类perl6虚拟机环境。它设计用perl6语法来实现高级别 虚拟机(比如MoarVM and JVM)编译器和类库。

NQP使用什么语言开发的?

NQP是以下各部分构成 (1) NQP代码, (2) 底层虚拟机使用的各种语言 (3) 一些第三方的 C和库, 以及(4)一些早期编译进程的运行时启动文件

perl6是Lisp嘛?

不是说是,也不能说完全不是 (not (not Nil))

Meta问题和文化

为什么Perl6名字要带Perl?

关于这个问题教主Larry这样回答的: Rule 1

… As opposed to some other name that did not imply all the things that the higher number might indicate on other languages.

… 相比较换个不能说明任何事情的名字,一个高的版本号也可能暗示是一个完全不同语言。

perl社区认为Perl5和Perl6是姊妹语言,他们有很多共同点,解决了许多相同的问题, 但是Perl6并不为了取代Perl 5。事实上,两种语言互相影。

Perl6怎么样了? 现在可以了么?

尽管编程语言和他们的编译不是一个是与非得二元问题。因为还牵扯到语言本身和实现的 问题,他们会变越来越好用。根据个人需求的不同,perl6及编译器可能是可用或者不可用。 (截止目前,目前99.9的功能都实现了,只是还稍微有点慢 __译者)。

6.c版本(2015圣诞节)是Perl 6首次正式发布版本,发布包括一个验证套件和的编译器。

我为什么要学习Perl6? 他有啥重大改进和特性?

perl6实现了通常其他程序中没有的许多伟大的想法。虽然有几种语言提供了这些特性中的部分, 但没有一种语言能支持所有这些:

  • Perl6提供了过程式,面向对象和函数式编程方法.
  • 简单一致的语法, 数据结构使用类型前缀标志严格区别.
  • 全字符Unicode支持,包括 Annex #29.
  • 清晰,更可读的正则表达式;更多的功能,更深层次的可用性.命名正则表达式提高可用性.
  • Junctions允许多种可能的测试; 例如, $a == 1|3|42 ( 表示 $a 等于1,3 或者 42).
  • 动态变量提供一个可选的词法作用域,对应于全局变量.
  • 立足于通过组合性和词法范围来阻止“超距行为“; 例如, imports一直为法范围.
  • 易于理解地一致作用域规则和闭包.
  • 强大的面向对象,支持类和角色(一切皆对象)。继承,子类型,代码重用.
  • 对象和元对象的内省机制 (金字塔一样一层层堆起来).
  • 元对象协议允许元组编程,而无需代码生成和解析.
  • 子例程和方法签名,方便地位置和命名参数解包。
  • 基于数量,类型和可选附加代码的不同签名对特定子例程(方法)实现多路指配.
  • 对未知子例程和不可能调度的编译时错误报告。
  • 可选地、无额外运行时损耗的渐进类型检测。还支持可选类型注解。
  • 基于编译/运行状态內省的高级错误报告,实现更有用,更精确地错误信息。
  • 代码快(比如BEGIN/END)允许代码在范围入口和结尾运行, 循环的first/last/next以及其他很多更特殊的语法。
  • 高级并发模型,实现隐式、显式多进程处理,超越基本的线程和锁机制。 perl6的并发机制还提供了丰富地(可插拔)工具集。
  • 多核越来越普遍,perl6的并发可以用隐式(例如,用>>.方法)和显式(start { code })。摩尔定律都要失效了,支持多核才是硬道理。
  • 结构化语言支持以实现代码的异步执行。
  • Supplies允许事件驱动的代码执行 (比如定时器,信号,或者文件系统事件).
  • 利用react/whenever/supply关键字方便构建交互,开发事件驱动的应用.
  • 尽可能惰性求值,需要时时候才即时出值。例如,懒列表,甚至无限懒列表,比如斐波纳契序列或所有素数。
  • 原生数据类型,更快,更底层地处理。
  • 非常简单基于NativeCall的对外C/C++的接口。
  • Inline::Perl5和Inline::Python接口非常便捷链接Perl5(CPAN)/Python模块。
  • 可同时安装和加载模块的多个版本。
  • 便捷的跟新/升级策略,简化系统管理。
  • 利用Rats(有理数)简单实现精度无损的数值计算(比如1/3,而不是用浮点数来近似估算)。
  • 实现数据和代码解析的可扩展语法(Perl6就是用他解析自己)。
  • Perl6是一个支持多变的语言 (定义自己的函数,操作符,特征和数据类型, 修改自定义的解析器)。
  • 大量可选的数据类型,加上可自定义的类型。
  • 多维度构型或者原生数组,合适的边界检查。
  • 当特定条件发生时,可在语法解析期间任何随时执行代码。
  • 自定义一个操作符或者增加一个trait特征就像定义子例程一样简单。
  • 给任何操作数自动生成超操作符(系统的或者自定义的操作皆可)。
  • 运行在多种后端虚拟机。目前有MoarVM和JVM, 正在开发中的JavaScript,还可能更多的。
  • JIT热代码路径运行时优化。
  • 小系统(例如,树莓派)和大型处理器上的运行。
  • 垃圾回收机制: 不及时的销毁,所以没有必要的引用计数,使用phasers的时间行为。
  • 属性可以在运行时混合到任何实例化对象。例如, 允许添加范围外数据。
  • 具有多路劲分配和自动使用消息生成的MAIN子例程,实现快捷的命令行访问接口。
  • 用更少的代码实现更紧凑的程序。命名的霍夫曼编码实现更好的可读性。
  • 用简单的递归接口定义懒列表,任何类通过提供单个方法提供最小化支持。
  • perl6秉承了perl一贯原则: “Perl是不同的。简而言之,Perl旨在”使容易的工作变得容易,使困难的工作变得可能”。和”条条大道通罗马”。 现在会有更多-Ofun添加进来。请浏览 特性对比矩阵 查看更多实现细节.

Perl6够快么?

那要取决于你要拿它做什么。Rakudo开发的秉承“工作的更合适,而不更快”的宗旨。一些部分 已经足够快,还有一些还需要改善。

相比较其他动态语言perl6提供了很多JIT特性,还有很大性能提升空间。在一些问题上已经比perl5快了。

perl5程序员应该了解perl了内置了更多的函数,简单的基准性能测试并不能说明什么问题,除非你perl5 测试用例包括了诸如Moose,类型检测模块等复杂的项目。

下面提供了写粗略的基准脚本,表明如果使用了复杂的模块的任务上Perl6比Perl5要快,与此同时,如果 不涉及这些重模块Perl5则会更快。

在你的系统运行下面脚本,结果可能会让你大吃一惊。

例子:

=begin code :skip–test

# Perl6 版本

use v6.c;

class Foo { has $.i is rw };

for 1..1_000_000 –&gt; $i {

my $obj = Foo.new;

$obj.i = $i;

}

# Perl5 版本

package Foo;

use Moose;

has i =&gt; (is =&gt; ‘rw’);

__PACKAGE__–&gt;meta–&gt;make_immutable;

for my $i (1..1_000_000) {

my $obj = Foo–&gt;new;

$obj–&gt;i($i);

}

1;

# 另一个Perl5版本,相比较Moose/Perl6版本,提供少量仅仅需要特性,更简单程序。

package Foo;

use Mojo::Base –base;

has ‘i’;

for my $i (1..1_000_000) {

my $obj = Foo–&gt;new;

$obj–&gt;i($i);

}

1;

#  一个脚本运行在perl5 (with perl -Mbigint)和perl6下

my ($prev, $current) = (1, 0);

for (0..100_000) {

($prev, $current) = ($current, $prev + $current);

}

print $current;

=end code

</code><code>

]]>
http://ijz.me/?feed=rss2&p=983 0
网站目录防篡改程序,perl web目录md5文件验证 http://ijz.me/?p=925 http://ijz.me/?p=925#comments Tue, 20 Sep 2016 09:05:20 +0000 http://ijz.me/?p=925 有时候站点,有bug,很容易会被人修改,添加其他乱七八糟的东西,针对这类问题,常见的做法:1、修改升级程序漏洞。2、用WAF主动防御(用第三方免费cdn,也提供这类防御)。

这儿介绍第三种方法(如果网站固定文件不变的情况下)
网站部署好后,通过对站点所有文件的计算MD5值,并保存在一个文件中。然后以后可以手动或者crontab,监控程序等定期对保存文件中的文件生成md5值和已有的md5值对比,如果发现值对不上,则说明文件被篡改了。

程序perl:

#!/usr/bin/perl

use strict;
use warnings;
use Digest::MD5 qw(md5_hex);


my $dir=shift;
# 此处默认为检查md5值。
md5check($dir);
# 如果需要开始生成web目录的md5值,注释掉上面一句,把下面一句启用
#md5init($dir);
sub md5_sum {

 my ($file_name,$mode)=@_;
 my ($FD,$ctx, $md5);
   open ($FD,$file_name) or die "Can't open /'$file_name/': $!";
     $ctx = Digest::MD5->new;
       binmode($FD) if $mode;
     $ctx->addfile($FD) || die "$!n";
    $md5 = $ctx->hexdigest;
   close $FD;
 return $md5;
}

sub md5check {
my $file=shift;
open(my $fd, '<',$file) or die "$file: $!n";
print $file;
while (<$fd>){
        my ($name, $sum) = split /s+/;
        if ($sum eq md5_sum($name,1)){
                print "$name OKn";
        }
        else{
          print "$name FAILEDn";
        }
}

close $fd;

}
# 遍历目录计算md5值
sub md5init {

    my $fd=shift;
    my $md5value;
    if ( -f $fd ){
            if ( -T $fd ) {
                #print "按照文本模式进行计算MD5!n";
                $md5value =md5_sum($fd,0);
                print "$fdt$md5valuen";
            }elsif( -B $fd ){
                #print "二进制文件用binmod计算MD5!n";
                $md5value =md5_sum($fd,1);
                print "$fdt$md5valuen";
            }else{
                #print "其他文件,按照bimmod计算!n";
                $md5value = md5_sum($fd,1);
                print "$fdt$md5valuen";
            }
     }
     elsif( -d $fd ){
        my $file_md5;
      # print "开始验证目录下所有文件:n";
       opendir (my $DH,$fd) or die "Can't open dir $fd: $!";
         for(readdir $DH ){
         my $file=$fd.'/'.$_;
      # 上级目录..,本目录. 以及连接文件跳过
         next if ($file =~ m{/.$} || $file =~ m{/..$} || -l $file );
         md5chek($file);
        }
       closedir $DH;
    }

}

以上程序保存成文件,比如filemd5check.pl

一、生成web的md5文件是时候:

注释掉

#md5check($dir);

md5init($dir);

然后执行  web目录  > webmd5-20160920

web目录换成自己实际的web目录 webmd5-20160920 为保存计算结果的文件,可以自定义

二、检查时候,用默认文件

perl filemd5check.pl  webmd5-20160920

 

 

]]>
http://ijz.me/?feed=rss2&p=925 1
批量检查zabbix guest用户登录 http://ijz.me/?p=919 http://ijz.me/?p=919#respond Thu, 18 Aug 2016 00:48:00 +0000 http://ijz.me/?p=919  

最近又有人挖坑zabbix的sql注入漏洞,此漏洞不在详细说了。此漏洞的利用有个条件必须要登录才行。zabbix如果不做安全配置的话,默认是guest用户空密码可以登录的。

为此写一个脚本检测是否禁用了guest用户,用来批量检查,加固。

use strict;
use warnings;
use LWP;
use Encode;
use Data::Dumper;


my $lwp = LWP::UserAgent->new;

my @url=qw(

http://192.168.1/zabbix
http://zabbix.ooxx.com
http://sb.zabbix.rc/zabbix
#... 添加和修改更多的地址


);
for (@url) {
  my $login_url = $_."/dashboard.php";
  print $login_url,":n";
  my $respos= $lwp->get($login_url);
  if ($respos->is_success) {
   my $res=$respos->content;
   print "please disable guest accesss!","n" if $res=~/menu_graphs/ms;
   print "good","n"   if $res=~/(<!-- Login Form -->)|(You are not logged in)/ms;
   }
  else {
        print "Login Error: ",$respos->status_line,"n";
   }

 }

上面是是多个地址批量检验的,同时没有兼顾新版本的zabbix,新版可能会报 404错误,下面在发一个检测单url的,同时兼顾新版本zabbix的

use strict;
use warnings;
use LWP;
use Encode;
use Data::Dumper;

my $url=shift @ARGV;
my $lwp = LWP::UserAgent->new;

my $login_url1 = $url."/zabbix.php?action=dashboard.view";
my $login_url = $url."/dashboard.php";

my $ok=check($login_url);
   $ok=check($login_url1) unless $ok;
 print "Login Error: ","n" unless $ok;

sub check {

    my $url=shift;
     print $url,":n";
    my $respos= $lwp->get($url);
    if ($respos->is_success) {
       my $res=$respos->content;
       print "please disable guest accesss!","n" if $res=~/menu_graphs|initPMaster/ms;
       print "good","n"   if $res=~/(<!-- Login Form -->)|(You are not logged in)/ms;
       return 1;
       }
     else {return 0};

}

使用方法:以上脚本保存为ztest1.pl

然后执行 perl ztest1.pl http://zabbix.org/zabbix

]]>
http://ijz.me/?feed=rss2&p=919 0
利用 Schwartzian Transform(施瓦茨变换) 进行排序 http://ijz.me/?p=910 http://ijz.me/?p=910#respond Thu, 21 Jul 2016 08:42:51 +0000 http://ijz.me/?p=910 Schwartzian Transform(施瓦茨变换) 是perl中一种高效的排序算法 ,详见http://en.wikipedia.org/wiki/Schwartzian_transform
在平时工作中,会有非常复杂的排序需求,比如,对文件所有的含有/RE/的行,按第一列升序,再按第二列降序排,…
诸如此类的排序,利用施瓦茨变换可以事半功倍。
施瓦茨变换的一般格式如下:

map { code_that_does_something_with( $_ ) } 
grep { code_that_selects_from( $_ ) }
sort { code_that_compares( $a, $b ) } @array

这里我举一个实例来说说明这个变化,有如下的的json数据:

cat dd
  [{
    "createdTime": 11,
    "versionId": "13a76a74-adc5-4c66-914a-07bb16a486ef"
  },
  {
    "createdTime": 55,
    "versionId": "99b26fce-2df8-4364-b13f-3fb89144d64b"
  },
  {
    "createdTime": 33,
    "versionId": "4e9ca6a1-1b1d-4586-9ff5-9411330c722d"
  },
  {
    "createdTime": 44,
    "versionId": "36859a25-afc4-42c7-bac4-685dc3761c41"
  }]

要求根据createdTime的值,取最大createdTime值的versionId,我们利用施瓦茨变换的perl单行实现排序,然后取第一行

perl -MJSON -000  -e  '
map{ print $_->[2],"n" }
sort{ $b->[1] <=> $a->[1] }
map{ [$_,$_->{"createdTime"},$_->{"versionId"}]} @{decode_json(<>)}' dd|head 1

相对比用perl脚本实现,取两个值,以createdTime为键,构造一个哈希,然后对哈希进行排序。

#!/bin/env perl
use JSON;

local $/;
open my $FD,'<','dd' or die;
my $code = <$FD>;
close $FD;
my $obj =  decode_json($code);
my %hash;
for(@{$obj}) {
  $hash{$_->{'createdTime'}}=$_->{'versionId'};

}

for (sort keys %hash) {
  print $hash{$_},"n";

}

 

]]>
http://ijz.me/?feed=rss2&p=910 0
快速扫描器(基于zmap扫描)perl包装 http://ijz.me/?p=854 http://ijz.me/?p=854#respond Tue, 14 Jun 2016 06:45:14 +0000 http://ijz.me/?p=854 之前我们用perl和nmap的一个端口扫描器,但是如果对大量的ip时候扫描会花费很大的时间。能不能先快速的实现扫描呢,有,这就是zmap利器

号称可以在一小时扫遍整个互联网,真是名副其实的快扫网。

确保安装了zmap 。centos可以 yum install zmap。

以下为对zmap包装的脚本,保存为scalzmap.pl 。

my $port=shift @ARGV;
my $file=shift @ARGV;
open $IP,'<',$file or die;
my @ip=<$IP>;
close $IP;
print  "Start scan.n";
my %result;
my $out=$port.".txt";
open my $OUT,'>',$out or  die $!;
for (@ip)
{
  next if /(#|$)/;
  #print $OUT $_ ;
  my $result=`zmap -p $port  $_`;
  print $OUT  $result;
  print "scan $_ ok!n";
}
close $OUT;
print "All done.n";

经过我们打包一层后,使用方法 perl zmap.pl 端口 ip.list

端口为一个端口比如 22 ,3306,6379 等 ip.list为要扫描的目标ip地址或者段

格式:
10.2.134.1/24
10.2.123.1/28

 
扫描结果,扫描的结果为端口.txt的ip列表,这个列表的ip表示该端口是通的,这个列表可以用于
之前我们用perl和nmap的扫描器的扫描目的。继续挖掘更多的信息。。。。更多就不说了

]]>
http://ijz.me/?feed=rss2&p=854 0
端口扫描(namp扫描)perl自动处理结果 http://ijz.me/?p=782 http://ijz.me/?p=782#respond Tue, 31 May 2016 07:17:49 +0000 http://ijz.me/?p=782 确保服务器上装了nmap 并能正常执行,
确保服务器上装了perl
chmod u+x scalport.pl

创建一个ip列表文件(一个ip一行)all.ip

执行 ./scalport.pl all.ip 开始扫描

结果保存为all.csv

#!/usr/bin/env perl
use warnings;
use strict;
my $filename=shift @ARGV;
open my $IN,'<',$filename or  die $!;
my @ip=<$IN>;

my $out;
   $out=(split /./,$filename)[-1] unless defined $out and $out eq "";
   $out=(split /./,$filename)[-2];
   $out.=".csv";
my $port=q(80,8080,3306,9200,6379,11211,21,22);
my @resul;
my $host;
print  "Start scan.n";
my %result;
open my $OUT,'>',$out or  die $!;
for (@ip)
{
  chomp;
  next if /(#|$)/;
  $host=$_;
  my $result=`nmap -T3 -sV   -p $port  $_ `;
  @resul= split /n/ms,$result;
  for(@resul) {
  chomp;
  next if /^$/;
  next if /Starting Nmap/;
  next if /Nmap scan report/;
  next if /PORT/;
  next if /filtered/;
  next if /Host is up/;
  next if /Service detection performed/;
  next if /Nmap done:/;
  next if /service unrecognized/;
  next if /SF/;
  next if /Service Info/;
  my $info="$host $_";
  $info =~s/s+/,/g;
  $info =~s//tcp//g;
  print $OUT $info."n";
  }
    print "scan $_ ok!n";
}

close $OUT;

扫描过程比较长,尤其是当ip较多时候,建议用 screen 执行

扫描结果搜索
显示为open 并且 显示服务名称(比如Tomcat 或者 Mysql) 或者nginx 并有版本显示的需要处理:

x.x.x.x,51366,open,ssh,OpenSSH,5.3,(protocol,2.0)
需要封禁sshd端口
x.x.x.x,3306,open,mysql MySQL 5.6.19
Mysql需要封禁端口
x.x.x.x,8080,open,http,Apache,Tomcat/Coyote,JSP,engine,1.1
Tomcat需要屏蔽版本信息
x.x.x.x,80,open,http,nginx 1.9.4
nginx 有版本信息的需要处理

]]>
http://ijz.me/?feed=rss2&p=782 0
利用perl-oneline快速定位网站攻击源并处理 http://ijz.me/?p=844 http://ijz.me/?p=844#respond Fri, 26 Feb 2016 08:18:38 +0000 http://ijz.me/?p=844

1、问题发现

在查看网站攻击信息,发现一个时间段流量徒增,猜测可能有攻击,记下当时的时间点,并截图

QQ图片20160216162446

这是百度免费cdn的免费统计信息,可见今天早上1点到2点有异常流量。

2、问题定位

(1)分析网站access的日志,分析1点日志

QQ图片20160216163045

可见确实有大量不同寻常的访问,可判断为对xmlrpc.php的攻击。

(2)对来源ip进行定位并统计次数

QQ图片20160216163426

可以明确看到是这两个ip在攻击,来源地都是美国

(3)对两个ip单独分析,分析其行为

QQ图片20160216163649

可见,这两个ip先通过搜索文章作者(访问/?author=x),找到用户名,然后对用户名和密码进行尝试攻击。

3、处理和后续扩展
首先对两个ip进行封禁

由于xmlrpc.php并没有实际中用到,直接删除,或者改名。

当然可以写一个自动处理脚本根据日志判断攻击ip,然后自动封禁,作为一个可持续的方案不错。

4、关于wp防护

注意多升级,可以尽可能的消除安全漏洞。
注意不用系统默认的用户。
用一些安全插件比如WPSecurty Scan,Better wp Securiry
可以用一些开源ids,比如snort等。

 

]]>
http://ijz.me/?feed=rss2&p=844 0
perl 实现打印匹配模式行及上下行的操作 http://ijz.me/?p=846 http://ijz.me/?p=846#respond Thu, 21 Jan 2016 21:25:39 +0000 http://ijz.me/?p=846

这个可能用的着,在看日志时候,比如搜索tomcat 错误日志的时候
1、perl One-liner实现

perl -ne '/RE/ and {push @a,$.};push @b,$_;END{for(@a){print $b[$_-2];print $b[$_-1];print $b[$_]}}' file

实现原理:把每一行保存在一个数组@b里,把匹配的行号保存在素组@a里,然后在END模块打印出来

2、perl脚本实现

#!/usr/bin/env perl
$re=shift;
$file=shift;
open $line,"<",$file or die;
while(<$line>)
{
   push @b,$_;
   $i++;
   chomp;
   /$re/ and push(@a,$i) ;
}
close $line;
for(@a)
{
print $b[$_-2];
print $b[$_-1];
print $b[$_];
}

保存为xx.pl 然后chmod u+x xx.pl
./xx.pl RE file

]]>
http://ijz.me/?feed=rss2&p=846 0