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

How to run a shell script on a Unix console or Mac terminal?

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


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

1
sh myscript

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

1
bash myscript

要启动可执行文件(这是具有可执行权限的任何文件);只需按其路径指定即可:

1
2
3
/foo/bar
/bin/bar
./bar

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

1
2
chmod +x bar
./bar

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

1
#! /usr/bin/env bash

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

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

关于/usr/bin/env的说明

最常见的情况是,您会看到散列刘海,如下所示:

1
#!/bin/bash

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

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

不幸的是,你不能这样做:

1
#!bash

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

1
#!/usr/bin/env bash

这种方法有一个缺点:根据posix,hashbang可以有一个参数。在这种情况下,我们使用bash作为env程序的参数。这意味着我们没有空间向bash传递参数。所以没有办法把像#!/bin/bash -exu这样的东西转换成这个方案。你必须把set -exu放在hashbang之后。

这种方法还有另一个优点:有些系统可能附带有/bin/bash,但用户可能不喜欢它,可能会发现它有问题或过时,并且可能在其他地方安装了自己的bash。在OSX(macs)上,苹果通常会发布过时的/bin/bash,用户使用类似于自制的东西安装最新的/usr/local/bin/bash。当您使用执行PATH搜索的env方法时,您会考虑到用户的偏好,并使用其首选的bash而不是其系统附带的bash。


要启动shell脚本"file.sh",请执行以下操作:

1
2
3
sh file.sh

bash file.sh

另一个选项是使用chmod命令设置可执行权限:

1
chmod +x file.sh

现在运行.sh文件,如下所示:

1
./file.sh


对于Bourne Shell:

1
sh myscript.sh

巴什:

1
bash myscript.sh


如果希望脚本在当前shell中运行(例如希望它能够影响目录或环境),则应该说:

1
. /path/to/script.sh

1
source /path/to/script.sh

注意,/path/to/script.sh可以是相对的,例如. bin/script.sh在当前目录下的bin目录中运行script.sh


"文件扩展.command terminal.app分配两个冰淇淋。双clicking在任何.command will execute文件信息。


第一,提供给执行权限: chmod +x script_name

  • 如果冰槽executable脚本: SH为运行脚本文件: sh script_name 行走的bash脚本文件: bash script_name
  • 如果冰executable脚本: ./script_name
  • 注意:如果你可以检查文件executable冰或不使用的是城市A’