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

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

1069657 次浏览

要启动shell脚本'file.sh':

sh file.sh


bash file.sh

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

chmod +x file.sh

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

./file.sh

对于伯恩壳:

sh myscript.sh

bash的:

bash myscript.sh

要运行一个不可执行的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。如果没有,您没有告诉内核它是什么,因此内核不知道使用什么程序来解释它。它可以是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中的一个目录中,当您想按名称运行程序时,系统应该能够找到您的程序。

可悲的是,你< em > < / em >不只是这样做:

#!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,但用户可能不喜欢它,可能发现它有bug或过时,可能在其他地方安装了他自己的bash。这通常是在OS X (mac)上的情况,苹果发布了过时的/bin/bash,用户使用Homebrew等工具安装了最新的/usr/local/bin/bash。当您使用env方法(执行PATH搜索)时,您将考虑用户的首选项,并使用他的系统附带的首选bash。

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

. /path/to/script.sh

source /path/to/script.sh

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

首先,给予执行权限:-
# EYZ0 < / p >

  1. 如果脚本不可执行:-
    运行sh脚本文件:—
    . sh # EYZ0 < br > 运行bash脚本文件:—
    . sh 李# EYZ0 < / >
  2. 如果脚本可执行:-
    . sh 李# EYZ0 < / >

< em >注意< / em >:你可以使用'ls -a'来检查文件是否可执行

文件扩展名.命令被分配给Terminal.app。双击任何.command文件将执行它。

另外,在同一个文件夹中运行解释器,仍然在脚本中使用# !hashbang

为例工作复制的php7.2可执行文件位于你好脚本旁边的文件夹中。

#!./php7.2
<?php


echo "Hello!";

运行它:

./hello

它们的行为是一样的:

./php7.2 hello

有良好文档的适当解决方案可以是工具linuxdeploy和/或appimage,这是在引子下使用这种方法。