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

就目前情况而言,这个问题不适合我们的问答形式。我们希望答案能得到事实、参考资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或广泛讨论。如果您觉得这个问题可以改进并可能重新打开,请访问帮助中心寻求指导。

八年前关闭的

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

当使用命令行时,shell语言似乎要容易得多。我觉得,例如使用bash比在ipython中使用shell配置文件要容易得多,尽管有报道与此相反。我想大多数人都会同意我的观点,即在中大型编程中,Python比bash更容易。我使用Python作为基础我最熟悉的语言是Perl和Ruby

我试着解释原因,但除了假设两者对字符串的不同处理与此有关外,我无能为力

这个问题的原因是,我希望开发一种在这两种语言中都可用的语言。如果你知道这样一种语言,请也发布它

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

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

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

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

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

    | Ruby | Bash
    -----------------------------------------
    编号| 123 | 123
    字符串|“123”| 123
    regexp |/123/| 123
    file | file.open('123')| 123
    文件描述符| IO.open('123')| 123
    URI | URI.parse('123')| 123
    命令|`123`| 123
    
  3. Python&Co.被设计成向上扩展到10000、100000甚至1000000行程序,Bash&Co.被设计成向下扩展到10个字符程序

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

  5. >p>编程基本上是数据流编程。没有人意识到,甚至连编写shell的人也不知道,但事实证明shell是相当好的,通用语言也不是那么多。在通用编程世界中,数据流似乎主要被看作是并发模型,而不是编程编程。阿迪格姆

我觉得,试图通过将功能或DSL连接到通用编程语言上来解决这些问题是行不通的。至少,我还没有看到令人信服的实现。还有RuSH(Ruby shell),它试图在Ruby中实现一个shell,rush,这是Ruby中shell编程的内部DSL,Hotwire,这是一个Python shell,但在我看来,没有一个能与Bash、Zsh、fish和friends相媲美

事实上,我知道,目前最好的shell是微软PowerShell,考虑到几十年来微软一直拥有最差的shellevar。我的意思是,COMMAND.COM?真的吗?(不幸的是,他们仍然有一个糟糕的终端。它仍然是命令提示符“什么?Windows 3.0?)从那以后就出现了”

PowerShell的创建基本上是忽略了Microsoft所做的一切(COMMAND.COMCMD.EXE,VBScript,JScript),而是从Unix shell开始,然后删除所有向后兼容的缺点(如命令替换的反勾号),并对其进行一点处理,使其更适合Windows(比如使用现在未使用的反勾号作为转义字符,而不是反斜杠,它是Windows中的路径组件分隔符)

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

Number 2是通过静态键入参数来解决的。因此,您可以只编写123,PowerShell知道它是字符串、数字还是文件,因为cmdlet(在PowerShell中调用shell命令)向shell声明其参数的类型。这有相当深刻的影响:与Unix不同,Unix中每个命令都负责解析自己的参数(shell基本上将参数作为字符串数组传递),PowerShell中的参数解析由shell完成。cmdlet将其所有选项、标志和参数、类型、名称和文档(!)指定给shell,然后shell可以在一个集中的位置执行参数解析、制表符完成、IntelliSense、内联文档弹出窗口等。(这不是革命性的,PowerShell的设计者认可数字命令语言(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还提供内置别名lsdirndash;事实上,只要有意义,它们都提供Unix和CMD.EXE别名

发表评论