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

时间:2009-04-09 11:36:26

标签: linux bash macos shell unix

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

7 个答案:

答案 0 :(得分:909)

要运行不可执行的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机器上,通常情况下,bash在不同位置都有一系列其他POSIX机器,例如/usr/xpg/bin/bash/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之类的内容转换为此方案。你必须在hashbang之后添加set -exu

此方法还有另一个优点:某些系统可能附带/bin/bash,但用户可能不喜欢它,可能会发现它有缺陷或过时,并且可能已在其他地方安装了自己的bash 。在OS X(Macs)上经常出现这种情况,其中Apple发布了过时的/bin/bash,用户使用Homebrew之类的东西安装了最新的/usr/local/bin/bash。当您使用执行env搜索的PATH方法时,您会考虑用户的偏好并使用他首选的bash而非他的系统附带的bash。

答案 1 :(得分:78)

启动shell脚本'file.sh':

sh file.sh

bash file.sh

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

chmod +x file.sh

现在运行.sh文件如下:

./file.sh

答案 2 :(得分:15)

对于bourne shell:

sh myscript.sh

对于bash:

bash myscript.sh

答案 3 :(得分:10)

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

. /path/to/script.sh

source /path/to/script.sh

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

答案 4 :(得分:0)

首先,给予执行许可: -
chmod +x script_name

  1. 如果脚本不可执行: -
    用于运行sh脚本文件: -
    sh script_name
    用于运行bash脚本文件: -
    bash script_name
  2. 如果脚本可执行: -
    ./script_name
  3. 注意 : - 您可以使用'ls -a'检查文件是否可执行

答案 5 :(得分:0)

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

答案 6 :(得分:0)

小的补充,从同一文件夹运行解释器,仍然在脚本中使用#!hashbang

作为示例,从 / usr / bin 复制的php7.2可执行文件位于 hello 脚本的文件夹中。

#!./php7.2
<?php

echo "Hello!"; 

要运行它:

./hello

行为与以下行为相同:

./php7.2 hello