Bash或KornShell(ksh)?

use*_*158 60 unix bash shell scripting ksh

我不是*nix的新手,不过最近我在提示时花了很多时间.我的问题是使用KornShell(ksh)或Bash Shell有什么好处?使用其中一个的陷阱在哪里?

希望从用户的角度理解,而不是纯粹的脚本.

Dav*_* W. 125

Kornshell和Bash之间的区别很小.一方面有一定优势,但差别很小:

  • BASH更容易设置显示当前目录的提示.在Kornshell中做同样的事情是hackish.
  • Kornshell有关联数组,BASH没有.现在,我最后一次使用关联数组是......让我想想......从来没有.
  • Kornshell处理循环语法更好一些.您通常可以在Kornshell循环中设置一个值,并在循环后使其可用.
  • Bash以更干净的方式处理从管道获取退出代码.
  • Kornshell具有printecho命令更好的命令.
  • Bash有标签完成.在旧版本中
  • Kornshell有rhistory命令,可以让我快速重新运行旧命令.
  • Kornshell的语法是cd old new它取代oldnew那边的目录和CD.当你在一个被调用的目录中/foo/bar/barfoo/one/bar/bar/foo/bar并且你需要cd到/foo/bar/barfoo/two/bar/bar/foo/barIn Kornshell时,你可以简单地完成cd one two并完成它.在BASH,你必须这样做cd ../../../../../two/bar/bar/foo/bar.

我是一个古老的Kornshell家伙,因为我在20世纪90年代学习了Unix,那时候就是它的选择.我可以使用Bash,但我有时会对它感到沮丧,因为在习惯中我使用Kornshell的一些小功能,BASH没有,它不起作用.因此,只要有可能,我将Kornshell设置为默认值.

但是,我要告诉你学习BASH.Bash现在已经在大多数Unix系统和Linux上实现,并且有更多的资源可用于学习BASH并获得帮助而不是Kornshell.如果您需要在BASH中做一些异国情调,您可以继续使用Stackoverflow,发布您的问题,您将在几分钟内得到十几个答案 - 其中一些甚至是正确的!

如果你有一个Kornshell问题并将其发布在Stackoverflow上,你将不得不等待一些过去他们的主要黑客过去,就像我从小睡中醒来,然后才得到答案.并且,如果他们当天在老年人的家中供应布丁,那就忘记得到任何回应.

BASH现在只是选择的外壳,所以如果你必须学习一些东西,那么也可以选择流行的东西.

  • 为了完整起见,bash版本4支持关联数组.我从来没有在任何一个shell中使用过AA,所以我不能说它们是否比Kornshell的实现更好,更好或更差. (6认同)
  • 在bash中,`!vi`将运行以字母'vi'开头的最后一个运行命令.如果您不确定该命令是否是您想要的命令,请使用`!vi:p`,它将打印命令并将其新添加到您的历史记录列表中,但不会实际运行它.然后,如果*是*你想要什么,一个简单的向上箭头 - 输入,或只是`!!`来运行它.参见`man bash`并搜索"HISTORY EXPANSION". (4认同)
  • "你通常可以在Kornshell循环中设置一个值,并在循环后使其可用." - 我发现那令人困惑的地狱.我当然支持变量应该只在其嵌套级别内而不是在嵌套级别之外. (3认同)
  • 它与将命令传递到“while read”循环有关。Kornshell 访问循环外的变量没有问题。但是,对于 BASH,该管道是一个子进程,一旦循环完成,您就会失去该值。有办法解决这个问题。 (3认同)
  • @EarlGray除非上一个命令是我的更改目录,否则它不起作用.有人指出我可以这样做`$ cd $ {PWD/foo/bar}`但输入有点长. (3认同)

小智 46

击.

各种UNIX和Linux实现具有各种不同的ksh源代码级实现,其中一些是真正的ksh,其中一些是pdksh实现,其中一些只是具有"ksh"个性的其他shell的符号链接.这可能导致执行行为的奇怪差异.

至少使用bash,你可以确定它是一个单一的代码库,你需要担心的是安装了什么(通常是最小的)bash版本.在几乎所有现代(而不是那么现代)的UNIX上编写了大量脚本,对bash的编程在我的经验中更加可靠.

  • 如果你只做最小公分母ksh,我同意.另一方面,真正的David Korn ksh93在脚本编写方面具有令人信服的优势:速度使其接近文本处理的"awk"; 原生浮点数学; namevars和关联数组甚至在没有运行最新版本的系统上; 等等 (3认同)

Hen*_*eld 29

我是个角色老手,所以我知道我从那个角度说话.

但是,我对Bourne shell,ksh88和ksh93感到满意,并且我知道哪些功能受支持.(我应该在这里跳过ksh88,因为它不再广泛分发.)

如需交互式使用,请根据您的需要选择.实验.我喜欢能够使用相同的shell进行交互式使用和编程.

我从SVR2上的ksh88到tcsh,到ksh88sun(增加了重要的国际化支持)和ksh93.我试过bash,并讨厌它,因为它压倒了我的历史.然后我发现了shopt -s lithist一切都很好.(该lithist选项可确保在命令历史记录中保留换行符.)

对于shell编程,如果你想要一致的编程语言,良好的POSIX一致性和良好的性能,我会认真推荐ksh93,因为许多常见的unix命令可以作为内置函数使用.

如果你想要便携性至少使用两者.并确保你有一个很好的测试套件.

炮弹之间有许多细微的差别.考虑例如从管道读取:

b=42 && echo one two three four |
    read a b junk && echo $b
Run Code Online (Sandbox Code Playgroud)

这将在不同的壳中产生不同的结果.korn-shell从后到前运行管道; 管道中的最后一个元素在当前进程中运行.在v4.x之前,Bash不支持这种有用的行为,即使这样,它也不是默认的.

另一个说明一致性的例子:echo命令本身,由于BSD和SYSV unix之间的分割而过时,并且每个都引入了他们自己不打印换行符(以及其他行为)的约定.在许多"配置"脚本中仍然可以看到这样的结果.

Ksh采取了一种激进的方法 - 并引入了print命令,它实际上支持两种方法(-n来自BSD 的选项,以及\c来自SYSV 的尾随特殊字符)

但是,对于严肃的系统编程,我推荐的不是shell,比如python,perl.或者更进一步,使用像puppet这样的平台 - 它允许您通过良好的审计来观察和纠正整个系统集群的状态.

壳牌编程就像在未知的水域游泳,或者更糟.

任何语言的编程都需要熟悉它的语法,接口和行为.Shell编程没有任何不同.

  • @foampile是的,这就是"互动使用"的含义. (2认同)
  • Re:你的`read`差异,在非交互模式下,实际上可以配置为现代bash - 请参阅`lastpipe`选项. (2认同)

小智 6

这有点像Unix vs Linux之战。大多数(如果不是全部)Linux发行版都安装了bash,ksh是可选的。大多数Unix系统(例如Solaris,AIX和HPUX)将ksh作为默认设置。

就我个人而言,我总是使用ksh,我喜欢vi补全,并且几乎所有东西都使用Solaris。


All*_*len 5

一方面,bash 具有制表符补全功能。仅此一点就足以让我更喜欢它而不是 ksh。

Z shell很好地结合了 ksh 的独特功能和 bash 提供的好东西,此外还有更多的东西。

  • 默认情况下,ksh 使用 <ESC><ESC> 作为补全,以防有人好奇。来源:http://kornshell.com/doc/faq.html (4认同)
  • ksh 具有补全功能,只是不能使用 tab 键。 (3认同)
  • `ksh --version`:“版本 sh (AT&T Research) 93t+ 2009-05-01”具有制表符补全和 Esc 补全。 (2认同)

Chr*_*Lee 5

我没有使用 ksh 的经验,但我使用过 bash 和 zsh。我更喜欢 zsh 而不是 bash,因为它支持非常强大的文件通配符、变量扩展修饰符和更快的选项卡完成。

这是一个快速介绍:http : //friedcpu.wordpress.com/2007/07/24/zsh-the-last-shell-youll-ever-need/


Jon*_*son 5

对于脚本,我总是使用ksh因为它平滑了gotchas

但我发现bash更适合交互式使用。对我来说,emacs键绑定和制表符完成是主要的好处。但这主要是习惯的力量,而不是ksh 的任何技术问题。