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

问题描述 投票:488回答:6

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

linux bash macos shell unix
6个回答
908
投票

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

sh myscript

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

bash myscript

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

/foo/bar
/bin/bar
./bar

要使脚本可执行,请为其提供必要的权限:

chmod +x bar
./bar

当文件可执行时,内核负责确定如何执行它。对于非二进制文件,可以通过查看文件的第一行来完成。它应该包含一个qazxsw poi:

hashbang

hashbang告诉内核要运行什么程序(在这种情况下,命令#! /usr/bin/env bash 使用参数/usr/bin/env运行)。然后,脚本将作为后续参数传递给程序(作为第二个参数)以及您为脚本提供的所有参数。

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

A note on bash

最常见的是,你会看到像这样的哈希爆炸:

/usr/bin/env

结果是内核将运行程序#!/bin/bash 来解释脚本。不幸的是,/bin/bash并不总是默认发货,并且在bash中并不总是可用。在Linux机器上通常是,有一系列其他POSIX机器,其中/bin在不同的地方发货,如bash/usr/xpg/bin/bash

因此,为了编写可移植的bash脚本,我们不能依赖于对/usr/local/bin/bash程序的位置进行硬编码。 POSIX已经有了解决这个问题的机制:bash。我们的想法是,您将程序安装在PATH中的一个目录中,并且当您希望按名称运行程序时,系统应该能够找到您的程序。

可悲的是,你不能这样做:

PATH

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

bash

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

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


78
投票

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

PATH

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

sh file.sh

bash file.sh

现在运行.sh文件如下:

chmod +x file.sh

15
投票

对于bourne shell:

./file.sh

对于bash:

sh myscript.sh

10
投票

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

bash myscript.sh

要么

. /path/to/script.sh

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


0
投票

首先,给予执行许可: - bin

  1. 如果脚本不可执行: - 对于运行sh脚本文件: - chmod +x script_name 用于运行bash脚本文件: - sh script_name
  2. 如果脚本是可执行的: - bash script_name

注意: - 您可以使用'ls -a'检查文件是否可执行


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.