如何在Unix控制台或Mac终端上运行shell脚本?

我知道它,忘记它,重新学习它。是时候写下来了

要运行不可执行的sh脚本,请使用:

sh myscript

要运行不可执行的bash脚本,请使用:

bash myscript

启动可执行文件(具有可执行权限的任何文件);您只需通过其路径指定它:

/foo/bar
/垃圾箱/酒吧
/巴

要使脚本可执行,请授予它必要的权限:

chmod+x条
/巴

当一个文件是可执行文件时,内核负责弄清楚如何执行它。对于非二进制文件,这是通过查看文件的第一行来完成的。它应该包含一个hashbang

#/usr/bin/env bash

hashbang告诉内核要运行什么程序(在本例中,命令/usr/bin/env与参数bash一起运行)。然后,脚本被传递到程序(作为第二个参数)以及作为后续参数提供给脚本的所有参数

这意味着每个可执行脚本都应该有一个hashbang。如果没有,您就不会告诉内核它是什么,因此内核不知道用什么程序来解释它。它可以是bashperlpythonsh,或者其他什么。(实际上,内核通常会使用用户的默认shell来解释文件,这是非常危险的,因为它可能根本不是正确的解释器,或者它可能能够解析其中的一些,但存在细微的行为差异,例如shbash之间的情况)

关于/usr/bin/env

最常见的情况是,你会看到这样的散列刘海:

#/bin/bash

结果是内核将运行程序/bin/bash来解释脚本。不幸的是,bash在默认情况下并不总是提供的,而且它也不总是在/bin中可用。虽然在Linux机器上通常是这样,但也有一系列其他POSIX机器在不同的位置提供bash,例如/usr/xpg/bin/bash/usr/local/bin/bash

因此,要编写一个可移植的bash脚本,我们不能依赖于对bash程序的位置进行硬编码。POSIX已经有了一个处理这个问题的机制:PATH。这样做的目的是将程序安装在PATH中的一个目录中,当您想按名称运行程序时,系统应该能够找到您的程序

遗憾的是,你不能这么做:

#!猛击

内核不会(有些可能)为您执行PATH搜索。有一个程序可以为您执行路径搜索,它叫做env。幸运的是,几乎所有系统都在/usr/bin中安装了env程序。因此,我们使用硬编码路径启动env,然后执行path搜索bash并运行它,以便它能够解释您的脚本:

#/usr/bin/env bash

这种方法有一个缺点:根据POSIX,hashbang可以有一个参数。在本例中,我们使用bash作为env程序的参数。这意味着我们没有空间将参数传递给bash。所以没有办法转换像#这样的东西/bin/bash-exu,用于此方案。您必须将set-exu放在hashbang之后

这种方法还有另一个优点:一些系统可能附带/bin/bash,但用户可能不喜欢它,可能会发现它有缺陷或过时,并且可能已经在其他地方安装了自己的bash。在OSX(Mac电脑)上经常出现这种情况,苹果提供过时的/bin/bash,用户使用类似于自制的东西安装最新的/usr/local/bin/bash。当您使用执行路径搜索的env方法时,您会考虑用户的偏好,并使用用户首选的bash,而不是系统附带的bash

发表评论