使用以下命令来运行一个非可执行的sh
脚本:
sh myscript
要运行一个非可执行的bash
脚本,请使用:
bash myscript
要启动一个可执行文件(任何拥有可执行权限的文件);您只需指定其路径:
/foo/bar
/bin/bar
./bar
要使脚本可执行,需要赋予它必要的权限:
chmod +x bar
./bar
当一个文件可执行时,内核负责决定如何执行它。对于非二进制文件,这是通过查看文件的第一行完成的。第一行应该包含一个hashbang
:
#! /usr/bin/env bash
哈希注释告诉内核运行哪个程序(在这种情况下,命令/usr/bin/env
将以参数bash
的形式运行)。然后,脚本会作为第二个参数传递给程序,并随后将您提供给脚本的所有参数作为子参数。
这意味着每个可执行的脚本都应该有一个哈希注释。如果没有,您没有告诉内核它是什么,因此内核不知道要使用哪个程序来解释它。可能是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
程序的位置。 POSIX已经有一个处理这个问题的机制:PATH
。其思想是将程序安装在PATH
中的一个目录中,系统应该能够按名称找到你要运行的程序。#!bash
内核不会(也许有些会)为你执行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
。这在OS X(Macs)上经常发生,因为Apple预装了过时的/bin/bash
,而用户使用Homebrew之类的工具安装了最新的/usr/local/bin/bash
。当您使用env
方法进行PATH
搜索时,您考虑到用户的偏好并使用他选择的bash而不是系统提供的bash。
启动shell脚本 'file.sh':
sh file.sh
bash file.sh
另一种选择是使用chmod命令设置可执行权限:
chmod +x file.sh
现在,请按照以下方式运行.sh文件:
./file.sh
sh myscript.sh
对于bash:
bash myscript.sh
如果你希望脚本在当前shell中运行(例如,你希望它能够影响你的目录或环境),那么应该这样说:
. /path/to/script.sh
或者source /path/to/script.sh
请注意/path/to/script.sh
可以是相对路径,例如. bin/script.sh
将在当前目录下的bin
目录中运行script.sh
。
首先,给予权限以执行:
chmod +x script_name
sh script_name
bash script_name
./script_name
注意:您可以使用“ls -a”命令检查文件是否可执行。
稍作补充,如果要在同一文件夹中运行解释器,仍需在脚本中使用#!hashbang。
例如,将从/usr/bin复制的php7.2可执行文件和一个名为hello的脚本放在同一文件夹中。
#!./php7.2
<?php
echo "Hello!";
运行它:
./hello
这两个行为完全相等:
./php7.2 hello
适当的解决方案和良好的文档可以是工具linuxdeploy和/或appimage,这是使用此方法的底层实现。
zsh
作为我的 shell,我应该使用hashbang
#! /usr/bin/env zsh
吗? - stefmikhail#! /usr/bin/env zsh
。 - johnsyweb