哪一个更好:
#!/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
。诚然,我没有使用过所有的系统,所以答案是基于我有限的经验。