Answers:
要运行不可执行的sh
脚本,请使用:
sh myscript
要运行不可执行的bash
脚本,请使用:
bash myscript
启动可执行文件(它是具有可执行权限的任何文件);您只需通过其路径指定它:
/foo/bar
/bin/bar
./bar
要使脚本可执行,请授予其必要的权限:
chmod +x bar
./bar
当文件是可执行文件时,内核负责确定如何执行该文件。对于非二进制文件,这可以通过查看文件的第一行来完成。它应包含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机器上通常是这样,但bash
在其他位置(例如/usr/xpg/bin/bash
或)也有许多其他POSIX机器在发货/usr/local/bin/bash
。
因此,要编写可移植的bash脚本,我们不能依赖于对bash
程序的位置进行硬编码。POSIX已经具有处理该问题的机制:PATH
。这个想法是将程序安装在其中一个目录中,PATH
并且当您要按名称运行程序时,系统应该能够找到您的程序。
可悲的是,您不能仅仅这样做:
#!bash
内核不会(可能会)PATH
为您搜索。不过有一个程序可以PATH
为您搜索env
。幸运的是,几乎所有系统都在其中env
安装了程序/usr/bin
。因此,我们开始env
使用硬编码的路径,然后进行PATH
搜索bash
并运行该路径,以便它可以解释您的脚本:
#!/usr/bin/env bash
这种方法有一个缺点:根据POSIX,hashbang可以有一个参数。在这种情况下,我们使用bash
用作env
程序的参数。这意味着我们没有空间将参数传递给bash
。因此,没有办法将类似的东西转换#!/bin/bash -exu
为这种方案。你必须把set -exu
改用hashbang代替。
这种方法还具有另一个优点:有些系统可能附带/bin/bash
,但用户可能不喜欢它,可能发现它有故障或过时,并且可能在bash
其他地方安装了自己的。在OS X(Macs)上通常是这种情况,其中Apple交付了过时的产品/bin/bash
,用户/usr/local/bin/bash
使用Homebrew之类的软件安装了最新版本。当您使用env
进行PATH
搜索的方法时,您会考虑用户的偏好,并使用他的首选bash而不是系统附带的bash。
zsh
用作外壳,可以使用hashbang
#! /usr/bin/env zsh
吗?
#! /usr/bin/env zsh
,如果(且仅当)的代码里面的脚本应该通过Z shell执行。
对于bourne shell:
sh myscript.sh
对于bash:
bash myscript.sh