为什么python(或ruby、perl等)没有取代bash成为系统shell?

关联问题:http://www.zhihu.com/question/20244763如果编程语言是否可以作为系统shell使用,与它的流行程度正相关,那为何python还没有成为标配的系统shell?选择python(或其它)作为系统shell,一定就比bash或者posix shell更经济吗?回复内容:
shell 是有很多缺(tuo)陷(xie)的。比如说一个最简单的例子,如果你下载的文件名字里面有很多空格,在准备批量操作比如归档的时候都会很麻烦。shell 的自动解析通常会把你搞得很惨。而且那东西还是个feature 对吧?那不是bug。其实这就是很典型的不适合用shell去解的问题嘛。你找个没有自动解析的工具,比如说随便哪种脚本语言都行啦。为什么选ruby呢?当然因为ruby有 irb 咯。irb(main):033:0> dir = ‘archive-dir’irb(main):034:0> dst = ‘your-destination-directory’irb(main):035:0> num = 16irb(main):036:0> lines = `ls -rt ~/downloads/ | tail -n #{num}`.split(“\n”)irb(main):037:0> lines.each { |l| print `mv “#{l}” #{dir}/#{dst}` } 这样一来就是这么简单了,其实就只有两行嘛。我只所以写那么多变量是因为我还有很多文件需要交互的去做的。那么我就只需要改变量,然后用箭头找历史,一路回车就行了。但是为什么 shell 还是不能够被取代呢?因为还有大量的交互式任务用 shell 的时候可以简单到不可想象的地步。diff -u flex,yacc -> bison,都是遵循 unix 的习惯。也许是类 unix 系统中,有太多太多的脚本是使用 shell 脚本写的,所以这个不应该轻易的改变。比如,如果我们自己编译过一些软件或者类库,我们一定会对 ./configure 这个文件不会陌生,这个就是一个用 shell 写(准确的应该说是生成的)的脚本。打开这个文件的第一行,你会看到 #! /bin/sh 这样的一段。我们都知道 sh 和 bash 是不一样的,sh 作为一种古老的 shell,在 linux 中已经基本上被 继任者 bash 代替了,但是那些 autoconf 的脚本依然继承了 sh 这个古老的惯性,也是为了兼容其他的系统吧,比如在 freebsd 中,默认安装就是没有 bash 的。所以,倒也不是哪一个好或者是哪一个不好,就是大家都习惯了,反正也没有什么太大的问题,几十年了也不好再改了。
原因很简单,历史习惯+没人做。说python不能做shell的我就呵呵了,知道scsh吗?scheme都能做shell凭啥python不能?说起来丢人,当初我还真动手要做一个pysh,弄了两周弄到兼容不同终端类型的时候实在不胜其烦放弃了。当时交互、解释执行、基本的io、管道都已经有雏形了。
我觉得是完全可以取代的。给你们看一下 clojure 如何调用 shell:

(require ‘[me.raynes.conch :refer [programs with-programs let-programs] :as sh])
user> (programs echo)
#’user/echo
user> (echo “hi!”)
“hi!\n”
user> (programs cat)
#’user/cat
user> (cat {:in “hi”})
“hi”
user> (cat {:in [“hi” “there”]})
“hi\nthere\n”

对于复杂的逻辑,python具有模块化的特性,比shell更好用。但是对于单条命令,用python是什么感受,每一条命令都要调用 http://os.xxx ,而且python的函数不像shell那样空格分隔,而是要加括号、逗号和引号的,那画面太美我不敢想。所以最好的方案就是两者并存,直接敲命令用shell,写脚本用python。事实上很多linux发行版自带python,用python取代shell写脚本是没问题的。
@余天升 同学说的“惯性”这一点很有道理,但身边有不少人,用 bash 多年之后在别人的推荐下改用了 zsh (包括我),几天就完全切换完成了。在得知 debian 系中 vi 只是 vim 的别名之后,养成打 vim 而不是 vi 的习惯的,也大有人在。因此,我认为特殊的不是 bash,而是 shell 这一类东西。shell 和其他脚本语言的区别是很重要的。所谓“shell”,首先得是操作系统界面(这也是 shell 的原义),其次才是一个编程语言。而操作系统的职能中,文件系统和进程管理是两块很重要的地方。因此 shell 十分强调文件和命令,这是其他脚本语言所不具备的。具体强调的方式,有语义上的,也有语法上的。考虑最简单的,用 vim 打开文件 a.c,用 shell 写是:

vim a.c

很显然,bash更简洁
python/ruby/perl 没有取代 bash 的必要,bash 是一个 domain-specific language,而 python 是个 general-purpose programming language,语言本身存在的目的本就不同,这也正是 dsl 存在的意义,可以参看维基百科相关条目。我们讨论这个问题的前提是在 *nix 的背景下,那就应该从 *nix 自身的发展历史寻找原因,也就不难理解为什么 python 永远不会做为 shell 的替代存在。unix 的初期硬件条件的限制决定了 *nix 的设计哲学,其中最重要的两点就是:一、一个工具只做一件事,并把它做好;二、工具之间通过 plain text 进行数据交换。这样的设计降低了系统的复杂度,只需要 shell 这样的胶水语言通过搭积木的方式即可完成很多复杂的任务。由于并不需要复杂的数据结构操作,shell 不需要成为像 python 或者 perl 这样完整的程序语言,而且这一条件到现在也没有发生变化。这里我比较赞同 @yegel 的观点,至于 @狼大人 对于 bash 语法的吐槽,我相信在未来相当长一段时间 bash 的语法不会彻底的改变。因为在 *nix 的世界里,shell 的实现并不只有 bash,可移植性是一个很重要的因素,被 @狼大人 吐槽的那些奇葩语法大部分都是 posix 定义的,也正是要感谢 posix 的存在,我们才能享受 *nix 带来的各种好处。另外,具有交互模式的语言并不一定就能做为 shell,成为 shell 的一个必要条件是符合 *nix 的设计哲学,成为一个胶水语言,做为工具之间沟通的媒介,至少实现 pipe 是必不可少的。
因为: bash 是拿来“用”的 python 是拿来“编“的
python?你想每次都call([“ls”, “path”])一次么?打括号一点都不好玩=。=

Posted in 未分类

发表评论