我知道它,忘记它,重新学习它。是时候写下来了
要运行不可执行的sh脚本,请使用:
sh myscript
要运行不可执行的bash脚本,请使用:
bash myscript
启动可执行文件(具有可执行权限的任何文件);您只需通过其路径指定它:
/foo/bar
/垃圾箱/酒吧
/巴
要使脚本可执行,请授予它必要的权限:
chmod+x条
/巴
当一个文件是可执行文件时,内核负责弄清楚如何执行它。对于非二进制文件,这是通过查看文件的第一行来完成的。它应该包含一个hashbang:
#/usr/bin/env bash
hashbang告诉内核要运行什么程序(在本例中,命令/usr/bin/env与参数bash一起运行)。然后,脚本被传递到程序(作为第二个参数)以及作为后续参数提供给脚本的所有参数
这意味着每个可执行脚本都应该有一个hashbang。如果没有,您就不会告诉内核它是什么,因此内核不知道用什么程序来解释它。它可以是bash,perl,python,sh,或者其他什么。(实际上,内核通常会使用用户的默认shell来解释文件,这是非常危险的,因为它可能根本不是正确的解释器,或者它可能能够解析其中的一些,但存在细微的行为差异,例如sh和bash之间的情况)
关于/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