shell脚本标头以获得最佳兼容性

shell脚本标头以获得最佳兼容性

哪一个更好:

  • #!/usr/bin/env sh
  • #!/bin/sh
  • 空/无标题

我曾经认为第一个是最好的,无论如何我发现在一些基于 Linux 的系统(如 Android)上缺少路径名,所以现在我认为拥有“可移植”shell 脚本的唯一方法是不包括任何标题...

答案1

就可移植性而言,您可以放心地假设#!/bin/sh在任何标准 Unix 或 Linux 系统上都会找到一个主要兼容 POSIX 的 shell,但仅此而已。

在 FreeBSD、OpenBSD 和 NetBSD(以及 DragonFly、PC-BSD 和其他一些衍生版本)中,bash 位于/usr/local/bin/bash(如果已安装),因此该/usr/bin/env方法提供了 Linux 和 BSD 之间的可移植性。

Android 不是标准的 Unix 或 Linux 系统。在我的未 root 的 Android 手机上,没有/usr/bin/env/bin/bash甚至不/bin/sh存在,系统 shell 是/system/bin/sh.

缺少#!(shebang) 的 shell 脚本将尝试在某些系统上调用它的 shell 中运行,或者可能/bin/bash在其他系统上使用不同的默认解释器(例如)。而同时可能在 Android 中工作,但不保证在其他操作系统中工作,用户可能会选择使用不是bash. (我在 FreeBSD 中使用 tcsh,它是默认 shell,无 shebang 的脚本由调用 shell 解释。)

所以从我坐的地方来看,看起来是这样的不可能创建一个可在 Android 和非 Android(Linux 或 Unix)系统之间移植的 shell 脚本,因为 Android 的处理方式不同。

答案2

根据我的经验,#!/bin/sh最终#!/bin/bash总是在我开发过的几个系统上找到合适的环境。我还没有遇到例外。我还发现它经常用于 shell 脚本相关的文本中,我认为这些文本的编写考虑到了不同读者的可移植性。

不能说同样的话#!/usr/bin/env。有些系统已经安装了它,#!/bin/env并且过去已经破坏了我的 python 脚本。所以,我会选择第二颗子弹。

以下是对我上述说法的一些支持:

在 CentOS 5.7 版本上,我得到以下信息:

$ which env
/bin/env

在 Ubuntu 12.04 精确穿山甲上:

$ which env
/usr/bin/env

此外,至少在一个较旧的系统中,我记得出于某种原因安装了管理员coreutils/opt可能不是最佳实践)。由于env是 的一部分coreutils,用户最终得到了它/opt/coreutils/bin/env。诚然,我没有使用过所有的系统,所以答案是基于我有限的经验。

相关内容