【问题标题】:Bash or KornShell (ksh)? [closed]Bash 还是 KornShell (ksh)? [关闭]
【发布时间】:2010-09-09 15:28:32
【问题描述】:

我对 *nix 并不陌生,但最近我花了很多时间在提示符上。我的问题是使用 KornShell (ksh) 或 Bash Shell 有什么好处?使用其中一个的陷阱在哪里?

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

【问题讨论】:

    标签: bash shell unix scripting ksh


    【解决方案1】:

    我是一名 korn-shell 资深人士,所以要知道我是从这个角度说话的。

    不过,我一直对 Bourne shell、ksh88 和 ksh93 感到满意,而且我最了解哪些功能支持哪些功能。 (我应该在这里跳过 ksh88,因为它不再广泛分布。)

    对于交互式使用,请选择适合您需要的任何内容。实验。我喜欢能够使用同一个 shell 进行交互使用和编程。

    我从 SVR2 上的 ksh88 转到 tcsh,再到 ksh88sun(增加了重要的国际化支持)和 ksh93。我尝试过 bash,但我讨厌它,因为 它使我的历史变平。然后我发现了shopt -s lithist,一切都很好。 (lithist 选项可确保在您的命令中保留换行符 历史。)

    对于 shell 编程,如果您想要一种一致的编程语言、良好的 POSIX 一致性和良好的性能,我强烈推荐 ksh93,因为许多常见的 unix 命令都可以作为内置函数使用。

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

    shell 之间有许多细微的差别。例如,考虑从管道中读取:

    b=42 && echo one two three four |
        read a b junk && echo $b
    

    这会在不同的shell中产生不同的结果。 korn-shell 从后到前运行管道;管道中的最后一个元素在当前进程中运行。 Bash 直到 v4.x 才支持这种有用的行为,即便如此,它也不是默认的。

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

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

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

    Shell 编程就像在未知水域中游泳,或者更糟。

    使用任何语言进行编程都需要熟悉其语法、接口和行为。 Shell 编程也不例外。

    【讨论】:

    • “交互式使用”是指手动提示到提示的命令执行,而不是运行捆绑此类命令的脚本?
    • @foampile 是的,这就是“交互式使用”的意思。
    • 回复:您的 read 差异,在非交互模式下,实际上可以为现代 bash 配置 - 请参阅 lastpipe 选项。
    • @CharlesDuffy 正确,当我写这篇文章时它是可用的 - 但是,它仍然不是默认行为 - 你需要 bash 4.2 或 4.3 和 lastpipe shopt。 Shopt 选项很尴尬,因为它们的设置实际上会触发语法错误。
    【解决方案2】:

    Kornshell 和 Bash 之间的差异很小。两者相比有一定的优势,但差异很小:

    • BASH 更容易设置显示当前目录的提示。在 Kornshell 中做同样的事情是 hackish。
    • Kornshell 有关联数组,而 BASH 没有。现在,我最后一次使用关联数组是......让我想想......从来没有。
    • Kornshell 更好地处理循环语法。您通常可以在 Kornshell 循环中设置一个值,并在循环后使其可用。
    • Bash 以更简洁的方式处理从管道获取退出代码。
    • Kornshell 有print 命令,比echo 命令好很多。
    • Bash 有制表符补全。在旧版本中
    • Kornshell 有 r 历史命令,可让我快速重新运行旧命令。
    • Kornshell 的语法为cd old new,它将您目录和CD 中的old 替换为new。当您在名为/foo/bar/barfoo/one/bar/bar/foo/bar 的目录中时,这很方便,并且您需要 cd 到/foo/bar/barfoo/two/bar/bar/foo/bar 在 Kornshell 中,您只需执行cd one two 并完成它。在 BASH 中,您必须cd ../../../../../two/bar/bar/foo/bar

    我是一个老 Kornshell 人,因为我在 1990 年代学习了 Unix,而那是当时选择的 shell。我可以使用 Bash,但有时我会对此感到沮丧,因为习惯上我会使用 Kornshell 具有的一些小功能,而 BASH 没有而且它不起作用。因此,只要有可能,我都会将 Kornshell 设置为默认值。

    但是,我要告诉你学习 BASH。 Bash 现在在大多数 Unix 系统和 Linux 上都实现了,而且有比 Kornshell 更多的资源可用于学习 BASH 和获得帮助。如果你需要在 BASH 中做一些奇特的事情,你可以在 Stackoverflow 上发布你的问题,几分钟后你会得到十几个答案——其中一些甚至是正确的!

    如果您有 Kornshell 问题并将其发布在 Stackoverflow 上,您将不得不等待像我这样的资深黑客从午睡中醒来,然后才能得到答案。而且,如果那天他们在敬老院提供布丁,那就别再得到任何回应了。

    BASH 现在只是首选的 shell,所以如果你必须学习一些东西,不妨选择流行的。

    【讨论】:

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

    在大多数 UNIX 系统中可用,ksh 符合标准、设计清晰、功能完善。 我认为书籍,ksh 中的帮助已经足够清晰,尤其是 O'Reilly 的书。 Bash 是一个群众。我只在家里将它作为 Linux 的 root 登录 shell。

    对于交互式使用,我更喜欢 Linux/UNIX 上的 zsh。我在 zsh 中运行脚本,但我会在 AIX ksh 中测试我的大部分脚本和函数。

    【讨论】:

      【解决方案4】:

      Bash 是 Linux 的标准。
      我的经验是 bash 比 ksh 或 csh 更容易找到帮助。

      【讨论】:

      • 我会说 basha 标准。 ;-)
      • bash 只是 Linux 的标准。原始的 Bourne shell (sh) 是跨平台脚本的标准。
      • Posix-sh 是(或者可能“应该”)跨平台脚本的标准。
      • 更正:Bash 是 Linux 的标准。
      • 在 Debian 上,标准的 /bin/sh 实际上是破折号。
      【解决方案5】:

      重击。

      各种 UNIX 和 Linux 实现具有各种不同的 ksh 源代码级别实现,其中一些是真正的 ksh,其中一些是 pdksh 实现,其中一些只是指向具有“ksh”特性的其他一些 shell 的符号链接。这可能会导致执行行为出现奇怪的差异。

      至少对于 bash,您可以确定它是一个单一的代码库,您只需要担心安装了什么(通常是最低)版本的 bash。在几乎所有现代(以及不太现代的)UNIX 上编写了大量脚本后,根据我的经验,对 bash 的编程更加可靠。

      【讨论】:

      • 如果你只做最小公分母 ksh,我同意。另一方面,正版 David Korn ksh93 在脚本编写方面具有引人注目的优势:速度接近 awk 进行文本处理;本机浮点数学;名称变量和关联数组,即使在未运行最新版本的系统上;等
      【解决方案6】:

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

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

      【讨论】:

      • “互动使用”是什么意思?
      • @foampile:当您在终端命令行中键入内容时。 ;-)
      • 我是这么认为的。谢谢
      【解决方案7】:

      这是一场 Unix 与 Linux 的战斗。大多数(如果不是全部)Linux 发行版都安装了 bash 并且 ksh 是可选的。大多数 Unix 系统,如 Solaris、AIX 和 HPUX,都默认使用 ksh。

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

      【讨论】:

      • HP-UX 提供 sh、csh 和 ksh 作为默认 shell。在 11.31 中,bash 包含在默认安装介质中。但是,鉴于世界上仍在运行的 10.20 的数量,ksh 仍然是管理 HP-UX 的更好选择。
      • 您可以在 bash 中使用 vi 补全和 set -o vi,并将其添加到您的 ~/.bashrc 文件中以使其持久化。这就是我的设置。
      【解决方案8】:

      我的答案是“选择一个并学习如何使用它”。它们都是不错的贝壳​​; bash 可能有更多的花里胡哨,但它们都具有您想要的基本功能。如今,bash 更加普遍可用。如果你一直在使用 Linux,那就坚持下去吧。

      如果您正在编程,尝试坚持简单的 'sh' 以实现可移植性是一种很好的做法,但是随着 bash 的普及,如今这些建议可能有点过时了。

      了解如何使用完成和你的 shell 历史;偶尔阅读手册页并尝试学习一些新东西。

      【讨论】:

      • 在撰写此答案时,从编程的角度来看,ksh93 可以说有更多的花里胡哨(首先想到的是关联数组和名称变量)——尽管这在随后的八年中发生了变化。它仍然有浮点数学,而 bash 仍然缺乏。
      【解决方案9】:

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

      这里有一个简短的介绍:http://friedcpu.wordpress.com/2007/07/24/zsh-the-last-shell-youll-ever-need/

      【讨论】:

        【解决方案10】:

        @foxxtrot

        实际上,标准的 shell 是 Bourne shell (sh)。 Linux 上的 /bin/sh 实际上是 bash,但如果你的目标是跨平台脚本,你最好坚持使用原始 Bourne shell 的功能或将其编写为 perl 之类的东西。

        【讨论】:

        • 请注意,如果 /bin/sh (sym) 链接到 bash,则 bash 的行为会有所不同:如果使用名称 sh 调用 bash,它会尽可能地模仿 sh 的历史版本的启动行为尽可能,同时也符合 POSIX 标准。
        • 在 Debian 上,标准 /bin/sh 实际上是 dash,debian almquist shell。当#!/bin/sh 拒绝他们的“有效” bash 命令时,这让很多人感到惊讶。
        【解决方案11】:

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

        Z shell 将 ksh 的独特功能与 bash 提供的好东西很好地结合在一起,此外还有更多的东西。

        【讨论】:

        • ksh 已完成,只是没有使用 tab 键。
        • ksh --version: "version sh (AT&T Research) 93t+ 2009-05-01" 有tab-completion和Esc-completion。
        • 默认情况下,ksh 使用 作为补全,以防有人好奇。来源:kornshell.com/doc/faq.html
        【解决方案12】:

        Bash 是基准,但这主要是因为您可以合理地确定它已安装在每个 *nix 上。如果您打算分发脚本,请使用 Bash。

        很遗憾,我无法真正解决 shell 之间的实际编程差异。

        【讨论】:

        • 如果您计划分发脚本,请使用 posix-sh。 Bash 是一个很好的 shell,在 linux 上是默认的。较旧的 Unix 风格往往具有 sh、ksh 和 csh。在生产环境中,在所有系统上安装您选择的 shell 可能很难获得许可或宽恕。
        • 我们在工作中使用的 AIX(美国主要金融机构)上默认没有安装它,我希望它是。
        • 抱歉,Bash 不是“安装在每个 *nix 上”。尽管它可能在每个 GNU/Linux 发行版上都有。如果您支持 UNIX 或者您想遵循 POSIX,那么学习和使用 ksh,因为 ksh88(部分)是 sh 标准所基于的。如果您只使用 GNU/Linux 并且不关心与旧系统的兼容性,那么 Bash 就可以了。两者之间的大部分功能是可比的,但 Bash 让我很容易违反 POSIX。即使你明确告诉它不要这样做,它通常也会让你这样做。 Bash 中的 vi 模式也实现得很差。
        猜你喜欢
        • 2010-09-13
        • 2011-05-31
        • 2012-02-29
        • 2012-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-07
        • 1970-01-01
        相关资源
        最近更新 更多