如何在 Unix 控制台或 Mac 终端上运行 shell 脚本? [英] How to run a shell script on a Unix console or Mac terminal?

查看:40
本文介绍了如何在 Unix 控制台或 Mac 终端上运行 shell 脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know it, forget it and relearn it again. Time to write it down.

推荐答案

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

To run a non-executable sh script, use:

sh myscript

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

To run a non-executable bash script, use:

bash myscript

启动一个可执行文件(任何具有可执行权限的文件);您只需通过其路径指定它:

To start an executable (which is any file with executable permission); you just specify it by its path:

/foo/bar
/bin/bar
./bar

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

To make a script executable, give it the necessary permission:

chmod +x bar
./bar

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

When a file is executable, the kernel is responsible for figuring out how to execte it. For non-binaries, this is done by looking at the first line of the file. It should contain a hashbang:

#! /usr/bin/env bash

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

The hashbang tells the kernel what program to run (in this case the command /usr/bin/env is ran with the argument bash). Then, the script is passed to the program (as second argument) along with all the arguments you gave the script as subsequent arguments.

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

That means every script that is executable should have a hashbang. If it doesn't, you're not telling the kernel what it is, and therefore the kernel doesn't know what program to use to interprete it. It could be bash, perl, python, sh, or something else. (In reality, the kernel will often use the user's default shell to interprete the file, which is very dangerous because it might not be the right interpreter at all or it might be able to parse some of it but with subtle behavioural differences such as is the case between sh and bash).

最常见的是,你会看到这样的哈希刘海:

Most commonly, you'll see hash bangs like so:

#!/bin/bash

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

The result is that the kernel will run the program /bin/bash to interpret the script. Unfortunately, bash is not always shipped by default, and it is not always available in /bin. While on Linux machines it usually is, there are a range of other POSIX machines where bash ships in various locations, such as /usr/xpg/bin/bash or /usr/local/bin/bash.

为了编写可移植的 bash 脚本,我们不能依赖硬编码 bash 程序的位置.POSIX 已经有一个机制来处理这个问题:PATH.这个想法是你将你的程序安装在 PATH 中的目录之一中,当你想按名称运行它时,系统应该能够找到你的程序.

To write a portable bash script, we can therefore not rely on hard-coding the location of the bash program. POSIX already has a mechanism for dealing with that: PATH. The idea is that you install your programs in one of the directories that are in PATH and the system should be able to find your program when you want to run it by name.

遗憾的是,您不能就这样做:

Sadly, you cannot just do this:

#!bash

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

The kernel won't (some might) do a PATH search for you. There is a program that can do a PATH search for you, though, it's called env. Luckily, nearly all systems have an env program installed in /usr/bin. So we start env using a hardcoded path, which then does a PATH search for bash and runs it so that it can interpret your script:

#!/usr/bin/env bash

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

This approach has one downside: According to POSIX, the hashbang can have one argument. In this case, we use bash as the argument to the env program. That means we have no space left to pass arguments to bash. So there's no way to convert something like #!/bin/bash -exu to this scheme. You'll have to put set -exu after the hashbang instead.

这种方法还有另一个优点:有些系统可能附带一个/bin/bash,但用户可能不喜欢它,可能会发现它有问题或过时,并且可能安装了自己的bash 其他地方.这在 OS X (Macs) 上很常见,其中 Apple 提供过时的 /bin/bash 并且用户安装了最新的 /usr/local/bin/bash 使用 Homebrew 之类的东西.当您使用 env 方法进行 PATH 搜索时,您会考虑用户的偏好,并使用他喜欢的 bash 而不是他的系统附带的那个.

This approach also has another advantage: Some systems may ship with a /bin/bash, but the user may not like it, may find it's buggy or outdated, and may have installed his own bash somewhere else. This is often the case on OS X (Macs) where Apple ships an outdated /bin/bash and users install an up-to-date /usr/local/bin/bash using something like Homebrew. When you use the env approach which does a PATH search, you take the user's preference into account and use his preferred bash over the one his system shipped with.

这篇关于如何在 Unix 控制台或 Mac 终端上运行 shell 脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆