为啥脚本语言(例如 Perl、Python、Ruby)不适合作为 shell 语言? [关闭]

Posted

技术标签:

【中文标题】为啥脚本语言(例如 Perl、Python、Ruby)不适合作为 shell 语言? [关闭]【英文标题】:Why are scripting languages (e.g. Perl, Python, Ruby) not suitable as shell languages? [closed]为什么脚本语言(例如 Perl、Python、Ruby)不适合作为 shell 语言? [关闭] 【发布时间】:2011-04-07 22:48:35 【问题描述】:

bash、zsh、fish 等 shell 语言与使它们更适合 shell 的上述脚本语言之间有什么区别?

使用命令行时,shell 语言似乎要容易得多。对我来说,使用 bash 比在 ipython 中使用 shell 配置文件despite reports to the contrary 更顺畅。我想大多数人都会同意我的观点,即大部分中型到大型编程在 Python 中比在 bash 中更容易。我使用 Python 作为我最熟悉的语言,Perl 和 Ruby 也是如此。

我试图阐明原因,但除了假设两者对字符串的不同处理与此有关。

这个问题的原因是我希望开发一种可以在两者中使用的语言。如果你知道这样的语言,也请张贴出来。

正如 S.Lott 解释的那样,这个问题需要澄清一下。我问的是 shell language 与脚本语言的特性。所以比较的不是历史和命令行替换等各种交互(REPL)环境的特点。该问题的另一种表达方式是:

一种适用于复杂系统设计的编程语言能否同时表达有用的单行代码来访问文件系统或控制作业?编程语言可以有效地放大和缩小吗?

【问题讨论】:

【参考方案1】:

我认为这是一个解析的问题。 Shell 语言默认假定 $ command 意味着您的意思是要运行的命令,Python/Ruby 需要您执行 system("command") 或其他操作。 并不是他们不合适,只是还没有人真正做到过,至少我是这么认为的。 Rush http://rush.heroku.com/ 是 Ruby 中的一个示例尝试,Python 有“iPython”或类似的东西。

【讨论】:

感谢您的链接。我用过ipython,第一印象是Rush看起来好一点,可能是界面流畅的缘故。我需要多看一点。【参考方案2】:

shell 语言必须易于使用。您想键入一次性的丢弃命令,而不是小程序。 IE。你想输入

ls -laR /usr

不是

shell.ls("/usr", long=True, all=True, recursive=True)

这(也)意味着 shell 语言并不真正关心参数是选项、字符串、数字还是其他东西。

此外,shell 中的编程结构是一个附加组件,甚至并不总是内置的。 IE。考虑 if[ 在 (ba)sh 中的组合,seq 用于生成序列,等等。

最后,shell 具有您在编程中需要较少或不同的特定需求。 IE。管道、文件重定向、进程/作业控制等。

【讨论】:

感谢您的回答,但在我看来,这些差异似乎不是该语言所固有的。设计一个库很容易,所以在 Python 中你说shell.ls('usr', flags='laR')。甚至可以删除 shell 位和 flags= 位。我同意重定向和进程控制之类的东西在 shell 中进行了优化,因为它们在那里相关。 您仍然需要正确引用并平衡您的括号。你在这里提供了一个微不足道的论点,例如“ls --sort=time -R /bin /usr”呢? 您关于运行命令的观点适用于 Python,但并非所有正在考虑的语言:例如,`ls -laR /usr` 将在 perl 中执行。 那么你不是在使用 perl 而是通过 perl 执行 shell 命令。 无耻插件,我写了一个python库,希望能让python更容易使用:github.com/houqp/shell.py【参考方案3】:

如果你知道这样的语言,也请张贴出来。

Tcl 就是这样一种语言。主要是因为它被设计为主要是 CAD 程序的 shell 解释器。以下是一位核心 Python 程序员* 了解为什么 tcl 是这样设计的经验:http://www.yosefk.com/blog/i-cant-believe-im-praising-tcl.html

对我来说,我已经编写并一直在使用和改进 tcl shell(当然是用 tcl 编写的)作为我自制路由器上的主要 Linux 登录 shell:Pure tcl readline

我喜欢 tcl 的一些原因通常与它的语法与传统 shell 的相似性有关:

    最基本的 tcl 语法是command argument argument...。没有别的了。这与 bash、csh 甚至 DOS shell 相同。

    裸字被视为字符串。这再次类似于允许您编写的传统 shell:open myfile.txt w+ 而不是 open "myfile.txt" "w+"

    由于 1 和 2 的基础,tcl 最终只有很少的无关语法。你用更少的标点符号编写代码:puts Hello 而不是printf("Hello");。在编写程序时,您不会感到那么痛苦,因为您花了很多时间思考要写什么。当您使用 shell 复制文件时,您不认为您只是键入并且必须键入 (",); 一次又一次地很快就会很烦人。

*注意:不是我,我是铁杆 tcl 程序员

【讨论】:

非常好!我忘记了所有关于 Tcl 的事情。很久以前我对它进行了简短的介绍,我只是忘记了它对于我现在使用很长时间的一些 Cisco 路由器来说是一个非常好的 shell 接口。看起来 Tcl 是最接近它们之间的甜蜜点的地方。我将切换到 tclsh 几天看看效果如何。 现在有点不讨人喜欢。 Tcl 不如其他语言成功,你能说说为什么吗?我记得我对 math 命令不满意,可能是 OOP,但那是很久以前的事了。 首先,我想指出 tclsh 是一个非常基本的外壳:没有上下箭头历史,没有制表符完成等。我至少会推荐你使用 rlwrap tclsh 将其包装在 readline 中。或者更好的是,使用我上面链接的代码作为你的 shell。对于第二点,我认为这是因为大多数程序员对任何看起来不像 C 的东西感到不舒服。有趣的是,Netscape 最初将 Tcl 实现为浏览器脚本语言,但管理层想要看起来像 Java 语法的东西(这又是另一种类 C 语法)。 我在发表评论后确实查看了您的代码,我将使用它。说起不太像 C 的语言,你可能之前遇到过this。 我记得 TCL 的问题是政治问题。【参考方案4】:

谁说不是?看看Zoidberg。 REPLs (Read Eval Print Loops) 会产生糟糕的 shell,因为每个命令都必须在语法上正确,并且运行程序会变成:

foo arg1 arg2 arg3

system "foo", "arg1", "arg2", "arg3"

甚至不要让我开始尝试重定向。

因此,您需要一个自定义 shell(而不是 REPL)来理解命令和重定向以及您想要用来将命令绑定在一起的语言。我认为zoid(Zoidberg shell)做得很好。

【讨论】:

要去尝试一下zoid。你知道吗,有多少人使用他们的主要外壳? @Joel 我对此表示怀疑。它最后一次在 CPAN 上更新是在 2006 年。很难击败 bash。它无处不在,功能完整且维护良好。像zoid 这样的shell 玩起来很有趣,但我总是回到bashksh 是的,我也看到它没有被维护。我想知道它可能需要什么样的修整,我有兴趣使用具有这种能力的外壳。 我实际上已经修复了一些主要的错误(我是新的维护者!)。查看Zoidberg,了解您对基于 Perl 的 shell 的所有需求!【参考方案5】:

我能想到几个不同点;只是在这里思考,没有特定的顺序:

    Python & Co. 旨在擅长编写脚本。 Bash & Co. 旨在擅长编写脚本,绝对不会妥协。 IOW:Python 被设计为擅长脚本和非脚本,Bash 只关心脚本。

    Bash & Co. 是无类型的,Python & Co. 是强类型的,这意味着数字123、字符串123 和文件123 是完全不同的。但是,它们不是静态类型的,这意味着它们需要有不同的文字,以便将它们分开。 示例:

                    | Ruby             | Bash    
    -----------------------------------------
    number          | 123              | 123
    string          | '123'            | 123
    regexp          | /123/            | 123
    file            | File.open('123') | 123
    file descriptor | IO.open('123')   | 123
    URI             | URI.parse('123') | 123
    command         | `123`            | 123
    

    Python & Co. 旨在将向上扩展到 10000、100000 甚至 1000000 行程序,Bash & Co. 旨在将向下扩展到10 个字符程序。

    在 Bash & Co. 中,文件、目录、文件描述符、进程都是一流的对象,在 Python 中,只有 Python 对象是一流的,如果你想操作文件、目录等,你必须先将它们包装在 Python 对象中。

    Shell 编程基本上是数据流编程。没有人意识到这一点,即使是编写 shell 的人也没有意识到这一点,但事实证明,shell 非常擅长这一点,而通用语言则不然。在通用编程世界中,数据流似乎主要被视为一种并发模型,而不是一种编程范式。

我觉得试图通过将特性或 DSL 绑定到通用编程语言上来解决这些问题是行不通的。至少,我还没有看到令人信服的实现。有 RuSH(Ruby shell),它试图在 Ruby 中实现一个 shell,有 rush,这是 Ruby 中用于 shell 编程的内部 DSL,还有 Hotwire,这是一个Python shell,但 IMO 没有一个可以与 Bash、Zsh、fish 和朋友竞争。

实际上,恕我直言,目前最好的 shell 是 Microsoft PowerShell,考虑到现在的几个 十年,微软一直在拥有 最差的 shell evar。我的意思是,COMMAND.COM?真的吗? (不幸的是,他们仍然有一个蹩脚的终端。它仍然是从那以后一直存在的“命令提示符”,什么?Windows 3.0?)

PowerShell 基本上是通过忽略 Microsoft 所做的一切(COMMAND.COMCMD.EXE、VBScript、JScript)而创建的,而是从 Unix shell 开始,然后删除所有向后兼容的垃圾(如用于命令替换的反引号)和稍微按摩一下,使其对 Windows 更友好(比如使用现在未使用的反引号作为转义字符,而不是作为 Windows 中路径组件分隔符的反斜杠)。在那之后,就是魔法发生的时候。

他们从上面解决了问题 1 和 3,与 Python 相比基本上做出了相反的选择。 Python首先关心大型程序,其次才是脚本。 Bash 只关心脚本。 PowerShell 首先关心脚本,其次才是大型程序。对我来说,一个决定性的时刻是观看 Jeffrey Snover(PowerShell 的首席设计师)的采访视频,当时面试官问他可以用 PowerShell 编写多大的程序,Snover 毫不犹豫地回答:“80 个字符。”在那一刻,我意识到这是终于微软的一个“获得”shell编程的人(可能与PowerShell不是由微软的编程语言组开发的事实有关(即 lambda-calculus 数学书呆子),也不是操作系统组(内核书呆子),而是服务器组(即实际使用 shell 的系统管理员),我可能应该认真看看 PowerShell。

数字 2 通过静态输入参数来解决。因此,您可以只写123,P​​owerShell 知道它是字符串、数字还是文件,因为 cmdlet(这是在 PowerShell 中调用的 shell 命令)向 shell 声明其参数的类型。这具有相当深刻的影响:与 Unix 不同,其中每个命令都负责解析自己的参数(shell 基本上将参数作为字符串数组传递),PowerShell 中的参数解析由 shell 完成。 cmdlet 将它们的所有选项、标志和参数,以及它们的类型和名称以及文档(!)指定给 shell,然后它可以在一个集中的位置执行参数解析、制表符补全、智能感知、内联文档弹出窗口等。 (这不是革命性的,PowerShell 设计者承认像 DIGITAL 命令语言 (DCL) 和 IBM OS/400 命令语言 (CL) 这样的 shell 是现有技术。对于曾经使用过 AS/400 的任何人来说,这听起来应该很熟悉. 在 OS/400 中,您可以编写一个 shell 命令,如果您不知道某些参数的语法,您可以简单地将它们省略并按 F4,这将带来一个菜单(类似于HTML 表单)带有标签字段、下拉列表、帮助文本等。这仅是因为操作系统知道所有可能的参数及其类型。)在 Unix shell 中,此信息通常重复三遍:在参数解析代码中在命令本身、用于制表符完成的 bash-completion 脚本和手册页中。

数字 4 解决了 PowerShell 对强类型对象的操作这一事实,其中包括文件、进程、文件夹等内容。

数字 5 特别有趣,因为 PowerShell 是我所知道的唯一 shell,编写它的人实际上 知道 shell 本质上是数据流这一事实引擎并特意将其实现为数据流引擎。

PowerShell 的另一个优点是命名约定:所有 cmdlet 都命名为 Action-Object,此外,特定操作和特定对象也有标准化名称。 (同样,这对 OS/400 用户来说应该很熟悉。)例如,与接收某些信息相关的所有内容都称为Get-Foo。对(子)对象进行的所有操作都称为Bar-ChildItem。因此,ls 等价于 Get-ChildItem(尽管 PowerShell 还提供内置别名 lsdir - 事实上,只要有意义,它们就提供 Unix 和 CMD.EXE 别名以及缩写(@ 987654347@ 在这种情况下))。

杀手级功能 IMO 是强类型对象管道。虽然 PowerShell 是从 Unix shell 派生的,但有一个非常重要的区别:在 Unix 中,所有通信(通过管道和重定向以及通过命令参数)都是使用非类型化、非结构化字符串完成的。在 PowerShell 中,它们都是强类型的结构化对象。这是如此令人难以置信的强大,以至于我真的想知道为什么没有人想到它。 (嗯,他们有,但他们从来没有流行过。)在我的 shell 脚本中,我估计多达三分之一的命令只是用作其他两个在通用文本格式上不一致的命令之间的适配器.许多这些适配器在 PowerShell 中消失了,因为 cmdlet 交换结构化对象而不是非结构化文本。如果您查看内部命令,那么它们几乎包含三个阶段:将文本输入解析为内部对象表示,操作对象,将它们转换回文本。同样,第一阶段和第三阶段基本上消失了,因为数据已经作为对象进来了。

然而,设计者非常注意通过他们所谓的自适应类型系统来保持 shell 脚本的动态性和灵活性。

无论如何,我不想把它变成 PowerShell 广告。 PowerShell 有很多不是那么棒的地方,尽管其中大部分都与 Windows 或特定实现有关,而与概念无关。 (例如,它是在 .NET 中实现的,这意味着如果 .NET 框架由于其他需要它的应用程序而尚未在文件系统缓存中,则第一次启动 shell 可能需要几秒钟。考虑到你经常使用 shell 不到一秒钟,这是完全不能接受的。)

我想说的最重要的一点是,如果你想看看现有的脚本语言和 shell 工作,你不应该停留在 Unix 和 Ruby/Python/Perl/PHP 家族 >。例如,Tcl 已经被提及。 Rexx 将是另一种脚本语言。 Emacs Lisp 将是另一个。在 shell 领域,有一些已经提到的大型机/中型 shell,例如 OS/400 命令行和 DCL。还有Plan9的rc。

【讨论】:

对问题的两个部分都提供了很好的答案。关于第 2 点和第 4 点:这是因为静态类型本身,还是因为强制转换操作?在我所知道的大多数非 shell 语言(静态或动态)中,123 不能定义两种不同的类型。您还有解释 Powershell 的自适应类型系统的链接吗?谷歌似乎没有向我抛出任何我能理解的东西。 很好的答案!你还记得 Jeffrey Snover 的采访链接吗? 4 个月 13 票,然后 20 小时 84 票?我被reddited还是什么的? @Mauricio Scheffer:我浏览了 Channel9 上的几乎所有视频,甚至可以追溯到 PS 还被称为 Monad 的时候,但没有什么对我产生影响,抱歉。 @Dave:有一个名为 Pash (PoSh + Bash) 的项目,但三年前只有一个版本。 BUSH 和 FISH 远离 Bourne syntax,但它们仍然处理文本。 @codebliss:问题是关于 Python 作为一种 shell 语言。这里有趣的数字是一个 LOC @Muhammad Alkarouri:另一种看待它的方式:PowerShell 不支持多态性或重载。在具有多态性的语言中,语言根据参数的类型决定执行哪个过程。 (例如,x.ToString() 取决于 x which ToString() 被执行的类型。)在 PowerShell 中,这完全是双重的:语言决定解释参数的类型,基于在程序上。然而另一种解释是语法是根据参数类型动态构建的,因此只有解析标记的方法。 @Alexandru:PowerShell(因此得名)仍然是一个外壳,因此可以轻松执行程序(尽管根据可能需要引用的参数,它并非完全无痛)。因此,您可以像在其他任何地方一样使用 ImageMagick,而无需首先编写/查找 cmdlet 或包装它的 PowerShell 函数。 但是 PowerShell-native 实现可以更酷,例如通过传递图像对象并将图像过滤器实现为 cmdlet。我仍在考虑写一些东西来允许像Load-Image foo.bmp | Apply-Blur -Radius 5 | Save-Image x.png这样的东西。【参考方案6】:

由于两者都是正式的编程语言,你可以用一种语言做的事情,你也可以用另一种语言做。实际上这是一个设计重点问题。 Shell 语言是为交互式使用而设计的,而脚本语言则不是。

设计的基本区别在于命令之间的数据存储和变量的范围。在 Bash 等中,您必须跳过循环来存储值(例如,set a='something' 之类的命令),而在 Python 等语言中,您只需使用赋值语句(a = 'something')。在 shell 语言中使用值时,您必须告诉语言您想要变量的值,而在脚本语言中,您必须在需要字符串的立即值时告诉语言。这在交互使用时会产生效果。

ls 被定义为命令的脚本语言中

a = some_value

ls a*b  

a 是什么意思?这是否意味着 some_value *(无论 b 是什么)还是您的意思 'a'anystring'b'?在脚本语言中,默认值是存储在内存中的 a。)

ls 'a*b'  Now means what the Unix ls a*b means.

使用类似 Bash 的语言

set a=some_value

ls a*b   means what the Unix ls a*b means.

ls $a*b  uses an explicit recall of the value of a.

脚本语言使存储和调用值变得容易,并且很难对值具有瞬态作用域。 Shell 语言使存储和调用值成为可能,但每个命令的范围很小。

【讨论】:

谢谢。这就是我在问题中提到的“字符串的处理”,但你解释得更好。【参考方案7】:

可扩展性可扩展性? Common Lisp(您甚至可以运行 CLISP,可能还有其他实现,作为 UNIX 环境中的登录 shell)。

【讨论】:

【参考方案8】:

这是文化。 Bourne shell 已经快 25 岁了;它是最早的脚本语言之一,也是第一个很好解决 Unix 管理员核心需求的解决方案。 (即,将所有其他实用程序捆绑在一起并执行典型的 Unix 任务而不必每次都编译该死的 C 程序的“胶水”。)

按照现代标准,它的语法很糟糕,而且它奇怪的规则和标点符号风格(在 1970 年代每个字节都计算在内时很有用)使得非管理员很难渗透它。但它完成了工作。 其后代(ksh、bash、zsh)的进化改进解决了缺陷和缺点,而无需重新构思其背后的想法。管理员坚持使用核心语法,因为这很奇怪,没有其他东西可以更好地处理简单的东西而不妨碍。

对于复杂的东西,Perl 出现并演变成一种半管理半应用程序的语言。但是越复杂的东西,它就越被视为应用程序而不是管理工作,因此业务人员倾向于寻找“程序员”而不是“管理员”来做这件事,尽管正确的极客倾向于两者兼而有之。所以这就是重点所在,Perl 应用程序功能的进化改进导致了……嗯,Python 和 Ruby。 (这过于简单化了,但 Perl 是这两种语言的几个灵感来源之一。)

结果?专业化。管理员倾向于认为现代解释语言对于他们每天付钱做的事情来说太重了。总的来说,他们是对的。他们不需要对象。他们不关心数据结构。他们需要 命令。 他们需要 glue。 没有什么比 Bourne shell 概念更好地尝试命令了(除了可能已经提到的 Tcl这里); Bourne 已经足够好了。

程序员——如今他们必须越来越多地了解 devops——看看 Bourne shell 的局限性,想知道到底有没有人能忍受它。但是他们知道的工具,虽然他们肯定倾向于 Unixish 风格的 I/O 和文件操作,但并没有更好达到目的。我已经在 Ruby 中编写了诸如备份脚本和一次性文件重命名之类的东西,因为我比 bash 更了解它,但是任何专门的管理员都可以在 bash 中做同样的事情——可能更少行并且开销更少,但无论哪种方式,它都可以正常工作。

问“为什么当 Z 更好时每个人都使用 Y?”是很常见的问题? -- 但是技术的发展,就像其他一切的发展一样,往往会止步于足够好。“更好”的解决方案不会获胜,除非差异被视为破坏交易的挫败感。 Bourne 类型的脚本可能会让感到沮丧,但对于一直使用它的人以及它的本意工作来说,它总是能完成工作。

【讨论】:

我认为它可能会成为一些未来技术的灵感来源,这些技术将使用管道 (|) 作为基本概念。就像 javascript 被许多现代语言重新命名和复兴一样,然后node.js,同样的情况也可能发生在 shell 脚本上。【参考方案9】:

没有。


不,脚本语言可能不适合 shell。


问题在于宏语言与其他所有语言之间的二分法。

shell 与其他旧版宏语言(例如 nroff 和 m4)属于一个类别。在这些处理器中,一切都是字符串,处理器定义了从输入字符串到输出字符串的映射。

所有语言都跨越了某些界限,但通常很清楚系统的类别是否是,或者,嗯,我不知道官方术语......我会的说“一种真正的语言”。

当然,您可以用 Ruby 之类的语言输入所有命令,它甚至可能是真正的 shell 的次优选择,但它永远不会是宏语言。有太多的语法需要尊重。引用太多了。

但是,当您开始使用宏语言进行编程时,它有其自身的问题,因为必须做出太多妥协才能摆脱所有这些语法。输入的字符串不带引号。需要重新引入各种魔法来注入缺失的语法。我在 nroff 中做了一次 code-golf,只是为了与众不同。这很奇怪。宏语言中大型实​​现的源代码令人恐惧。

【讨论】:

非常感谢!这实际上是缺失的一点,是对我的“我试图阐明原因但无法表达的确切回应,除了假设两者对字符串的不同处理与此有关。”。看看有没有关于宏语言的研究会很有趣。【参考方案10】:

对于 windows 用户,我还没有觉得需要 powershell,因为我仍然使用 Jpsoft 的 4NT(现在是 Take Control),它是一个非常好的 Shell,具有很多编程能力。所以它结合了两全其美。

当您查看例如 IRB(ruby 解释器)时,必须很可能使用更多的单行代码对其进行扩展,以执行日常脚本或大量文件管理以及即时任务。

【讨论】:

【参考方案11】:

这个帖子启发我接管了基于 Perl 的 shell Zoidberg 的维护工作。经过一些修复后,它可以再次使用!查看user's guide 或使用您最喜欢的CPAN 客户端安装Bundle::Zoidberg

【讨论】:

【参考方案12】:

你问这个问题。不是每个人都同意 shell 语言更优越。一方面,_Why doesn't

不久前,一位朋友问我如何递归地在他的 php 脚本中搜索字符串。他在那些目录中有很多大的二进制文件和模板,这些文件可能真的让普通的 grep 陷入困境。我想不出使用 grep 来实现这一点的方法,所以我认为将 find 和 grep 一起使用是我最好的选择。

  find . -name "*.php" -exec grep 'search_string'  \; -print

这是在 Ruby 中重新设计的上述文件搜索:

  Dir['**/*.php'].each do |path|
    File.open( path ) do |f|
      f.grep( /search_string/ ) do |line|
        puts path, ':', line
      end
    end
  end

您的第一反应可能是,“嗯,这比原来的要冗长一些。”我只需要耸耸肩,顺其自然。 “扩展要容易得多,”我说。它可以跨平台运行。

【讨论】:

find . -name '*.php' | xargs -d \\n grep -l 'search_string' 将通过避免 N 次调用 grep 来更快地处理非大文件。 :) 问题不在于编写类似 shell 的脚本,而在于 shell 执行的语言。 所以你只是替换了一个 60 字符的脚本,如果你理解了 125 字符脚本的语法,这个脚本相当容易阅读(忽略额外的空格和换行符,你想让脚本真正可读)这不是更清楚。为什么你不想使用 python 或 ruby​​ 的一个很好的例子。 99.999% 的脚本是具有精确规范(或 1off 工作)的东西,它们永远不会被扩展。 Powershell 甚至有很好的语法,易于扩展,并且对于脚本的主要工作来说是简洁的。 @Voo “如果你理解语法,那是相当容易阅读的”......在那里你破坏了你自己的论点。除此之外,语法不仅需要理解,如果你要选择在有竞争对手的情况下重复使用它,还必须喜欢。我不喜欢 Powershell 的语法,所有的驼峰式外壳都很糟糕。 YMMV。 @alexis,xargs(除非给出相反的标志)和find -exec +(相对于-exec \;)都会将每个调用填写到允许的最大参数长度,所以不,它是小于 N(其中 N 是找到的项目数)。

以上是关于为啥脚本语言(例如 Perl、Python、Ruby)不适合作为 shell 语言? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥脚本语言不将 Unicode 输出到 Windows 控制台?

HexChat IRC 客户端的随机化脚本,在 Python 或 Perl 中

与python同类不同道之perl简记

数字IC设计脚本编程系列——Perl基本概念

为啥都说爬虫PYTHON好

Redis