是否建议使用zsh而不是bash脚本?[关闭]


25

我可以假设已经zsh安装了足够的人来运行带有

#!/usr/bin/env zsh

如shebang?

还是这会使我的脚本在太多系统上无法运行?

澄清:我对最终用户可能要运行的程序/脚本感兴趣(例如在Ubuntu,Debian,SUSE,Arch&c。上)


4
奇怪的问题。你的目标是谁?在某些圈子(Ruby-on-Rails Web开发人员)中zsh可能很受欢迎,而在其他圈子(银行业)中却鲜为人知。我认为,如果您需要对此方面的适当建议,则应该提供更多信息。
rahmu 2013年

一般的Linux最终用户世界。
Profpatsch

2
WRT是“一般的Linux最终用户世界”,zsh是非标准的。它不是默认安装(在大多数或所有发行版中)或任何东西都不需要的,因此大多数人都不会安装它。
goldilocks 2013年

3
我没有zsh安装任何系统,也不会为单个脚本安装它。即使bash通常可用,您甚至应该避免bashisms。
弗罗斯特斯

Answers:


29

为了便于携带,不可以。虽然zsh可以至少通过Cygwin在任何Unix或类Unix甚至Windows上进行编译,并且已打包为大多数开放源Unix类和一些商业类,但通常不包含在默认安装中。

bash另一方面bash,它像大多数非嵌入式Linux系统一样安装在GNU系统上(与GNU项目的外壳一样),有时也安装在Apple OS / X等非GNU系统上。在商业Unix方面,Korn shell(AT&T变体,尽管更多ksh88)是标准,并且两者兼有bashzsh并且位于可选软件包中。在BSD系统,首选交互shell往往是tcsh同时sh基于要么Almquist外壳或pdkshbashzsh需要安装的可选包为好。

zsh在Apple OS / X上默认安装。它甚至曾经在/bin/sh那里。默认情况下,可以在一些Linux发行版中找到它,例如SysRescCD,Grml,Gobolinux以及可能的其他发行版,但我认为没有任何主要发行版。

像一样bash,存在安装版本的问题,以及可用功能的问题。例如,使用bash3或查找系统并不少见zsh3。同样,不能保证您现在编写的脚本zsh5可以使用,zsh6尽管bash它们确实尝试保持向后兼容性。

对于脚本,我的观点是:使用POSIX shell语法,因为所有Unices都有至少一个称为sh(不一定在中/bin)的shell 能够解释该语法。然后,您不必太担心可移植性。而且,如果该语法不足以满足您的需要,那么您可能需要的不只是shell。

然后,您的选择是:

  • Perl是无处不在的(尽管您可能不得不将自己限制在旧版本的功能集中,并且不能对默认安装的Perl模块进行假设)
  • 将解释器及其版本(python 2.6或更高版本,zsh 4或更高版本,bash 4.2或更高版本...)指定为脚本的依赖项,方法是为每个指定依赖项的目标系统构建一个程序包,或者对其进行规定在脚本旁边附带的README文件中,或作为注释嵌入到脚本顶部,或者在脚本开头添加Bourne语法几行,以检查请求的解释程序的可用性并通过显式错误进行补救如果不是,则此脚本需要zsh 4.0或更高版本
  • 将解释器与您的脚本一起运送(请注意许可的含义),这意味着您还需要针对每个目标OS的一个软件包。一些解释器通过提供一种将脚本及其解释器打包到单个可执行文件中的方式,使操作变得更加容易。
  • 用编译语言编写。同样,每个目标系统一个软件包。

“ zsh-man”说“不”,我为您感到骄傲!^^可移植性!(所有警告)。+1。
奥利维尔·杜拉克 Olivier Dulac)

9

你不能。保证可用的是/bin/sh,基本上是原始的Bourne外壳。几乎所有(请注意“几乎”!)Linux安装都将使用bash,但是在* BSD系统上却很少使用(bash对GPL代码像bash一样有严重的疑虑)。我不知道Mac上的标准外壳是什么,但是同样,人们对GPL也存有疑虑。与Solaris相同。

zsh是一个利基外壳,它不是Fedora的默认安装(而且我不认为它是任何主要发行版的默认设置)。


6
当然不是原始的Bourne Shell,而是Posix兼容系统上的Posix Shell,在许多系统上是/ bin / sh,但不一定如此(在Solaris <=版本10上是/ usr / xpg4 / bin / sh)
审查员

好吧,“默认”安装并不重要。重要的是是否已安装。
Profpatsch 2013年

@Profpatsch,则默认安装非常相关(大概是由发行版确定人们真正使用了什么)。
vonbrand

2
@StephaneChazelas,“利基”,如“很少有用户使用” /“很少安装有它”。它可能是切成薄片以来最好的外壳,但是如果仅一小部分使用它,您就无法指望它会被安装在任何地方。
vonbrand

1
请注意,如果你考虑到绝大多数的Linux部署是当今嵌入式(认为Android,打印机,路由器,电视机,灯泡......),绝大多数的基于Linux的系统并没有bash(虽然这些系统很可能不是主要的目标脑子里想的提问)在OP
斯特凡Chazelas

2

我认为这实际上取决于您正在使用哪些zsh额外功能以及在哪里使用。如果您打算在不同的用户和系统之间分发脚本,我建议您使用bash甚至sh

同时,如果您的脚本旨在在整个组织中执行,并且您习惯在计算机上使用zsh(例如,相同的基本AMI),并且您的任务显然受益于诸如高级文件选择器之类的扩展名或来自http:/的其他内容/www.rayninfo.co.uk/tips/zshtips.html我要说吧!


1

就像声明的那样, bash在许多发行版的默认安装中通常可用。依靠,您的脚本将无法获得最大的用户群zsh

在设计脚本之前要回答的一个重要问题是“ 为什么在哪个shell中执行脚本很重要?

不同的外壳使用不同的语法或提供其他外壳可能不支持的其他外壳功能。要为“一般的Linux最终用户世界”编写脚本,请确定您的脚本是否使用依赖于特定Shell环境的任何语法或Shell函数。

例如,bashshell支持dashBourne shell或/bin/sh用户系统上指向的任何内容不支持的某些扩展。

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Feb 19  2014 /bin/sh -> dash

尝试执行echo {1..10}with /bin/sh比较/bin/bash,您将获得非常不同的输出。

这同样适用于zsh其中,同时支持大部分bash的语法,提供了不被支持额外的扩展和语法bash外壳。看到这个特定示例,表比较Shell

您可以bash坚持使用调用时可​​以起作用的脚本,从而扩大潜在的用户群#!/bin/sh -u。但是,这引起了另一个重要的问题:“ 为了获得更大的便携性而牺牲了什么?

确定与安全性,功能,效率或您认为脚本需要优先考虑的其他方面有关的差异是否值得付出。您可能不希望仅仅因为脚本可以在更多环境中工作而广泛使用具有已知安全漏洞的脚本。

为此编写了许多脚本,因此bash比较命令外壳程序将对这些脚本的支持用作标准。比脚本依赖zsh或shell环境专有的任何其他语法更多的人将能够运行您的脚本。

另外,请记住,您最终无法控制用户如何执行脚本(对于调试不同shell中的脚本也很有用):

请记住,如果您使用外壳程序读取外壳程序脚本(“ sh脚本名称”),而不是直接执行(“ ./scriptname”),则外壳程序会将外壳程序脚本开头的所有注释视为注释。特别是,将忽略指定执行脚本时使用的解释器的注释(“#!/ bin / sh -u”),以及该解释器旁边列出的所有选项。

因此,您可以做的最好的办法就是使脚本具有可移植性,只要不牺牲其功能即可。

您可能还会看到Bash编码约定-堆栈溢出


1
“正在牺牲什么”……看一下autoconf。他们像/ Original Bourne Shell中那样将/ bin / sh作为目标,因为所有shell都支持该(微小)功能集。他们为此付出了巨大的代价。
尔根A.艾哈德

1

您几乎可以保证的唯一事情是 /bin/sh。那可能是一个实际静态的链接外壳,也可能是到另一个外壳的链接。该其他外壳通常会检测到它称为sh并将在兼容模式下运行。

注意几乎第一句中。

我曾经研究过的每个类似Unix的系统都有它。他们中的许多人还安装了bash(但不是全部都安装了。例如,bash在某些BSD上默认未安装。某些Linux发行版附带DASH),而Debian Almquist shell代替了。

您可以保证的是您的安装说明。您可以在README文件中添加一行,说明需要zsh。如果构建软件包,则可以将zsh标记为依赖项。您可以使用autoconf / automake工具进行检查。您可以检查是否在安装脚本中找到了zsh(以/ bin / sh开头并尝试找到zsh,如果找到,请继续。如果未显示错误,例如。“警告:未安装ZSH。请阅读安装说明文件! “。)

我敢肯定,我忘记了更多选择。但是关键点是:

  • 在检查之前,您无法保证任何事情。
  • 您几乎可以保证/ bin / sh存在,并且可以对此进行检查。

POSIX需要/ bin / sh,AFAIU。就像它需要其他一些合理的实用程序。检查GNU自动没收的必要条件。
vonbrand

@vonbrand。POSIX不需要/bin/sh。它要求a sh在正确的环境(不必是默认环境)中按照指定的方式运行。/bin/sh可能不是POSIX shell。例如,在Solaris 10及更早版本的Solaris 10上,它仍然是Bourne shell,标准sh在中/usr/xpg4/bin
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.