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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/733824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:12:09  来源:igfitidea点击:

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

linuxbashmacosshellunix

提问by P-A

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

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

采纳答案by lhunath

To run a non-executable shscript, use:

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

sh myscript

To run a non-executable bashscript, use:

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

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

When a file is executable, the kernelis 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:

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

#! /usr/bin/env bash

The hashbang tells the kernel what program to run (in this case the command /usr/bin/envis 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 告诉内核要运行什么程序(在这种情况下,命令/usr/bin/env使用参数运行bash)。然后,脚本与您提供给脚本的所有参数一起作为后续参数传递给程序(作为第二个参数)。

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 shand bash).

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

A note on /usr/bin/env

注意事项 /usr/bin/env

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

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

#!/bin/bash

The result is that the kernel will run the program /bin/bashto interpret the script. Unfortunately, bashis 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 bashships in various locations, such as /usr/xpg/bin/bashor /usr/local/bin/bash.

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

To write a portable bash script, we can therefore not rely on hard-coding the location of the bashprogram. 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 PATHand the system should be able to find your program when you want to run it by name.

因此,要编写可移植的 bash 脚本,我们不能依靠硬编码bash程序的位置。POSIX 已经有一种处理这种情况的机制:PATH. 这个想法是您将程序安装在其中一个目录中,PATH并且当您想按名称运行程序时,系统应该能够找到您的程序。

Sadly, you cannotjust do this:

可悲的是,您不能只这样做:

#!bash

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

内核不会(有些人可能)会PATH为您搜索。不过,有一个程序可以PATH为您进行搜索,它名为env. 幸运的是,几乎所有系统都env/usr/bin. 所以我们开始env使用硬编码路径,然后PATH搜索bash并运行它,以便它可以解释您的脚本:

#!/usr/bin/env bash

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

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

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 bashsomewhere else. This is often the case on OS X (Macs) where Apple ships an outdated /bin/bashand users install an up-to-date /usr/local/bin/bashusing something like Homebrew. When you use the envapproach which does a PATHsearch, you take the user's preference into account and use his preferred bash over the one his system shipped with.

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

回答by P-A

To start the shell-script 'file.sh':

要启动 shell 脚本“file.sh”:

sh file.sh

bash file.sh

Another option is set executable permission using chmod command:

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

chmod +x file.sh

Now run .sh file as follows:

现在运行 .sh 文件如下:

./file.sh

回答by P-A

For the bourne shell:

对于伯恩外壳:

sh myscript.sh

For bash:

对于 bash:

bash myscript.sh

回答by Chas. Owens

If you want the script to run in the current shell (e.g. you want it to be able to affect your directory or environment) you should say:

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

. /path/to/script.sh

or

或者

source /path/to/script.sh

Note that /path/to/script.shcan be relative, for instance . bin/script.shruns the script.shin the bindirectory under the current directory.

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

回答by Vineet Jain

First, give permission for execution:-
chmod +x script_name

首先,授予执行权限:-
chmod +x script_name

  1. If script is not executable:-
    For running sh script file:-
    sh script_name
    For running bash script file:-
    bash script_name
  2. If script is executable:-
    ./script_name
  1. 如果脚本不可执行:-
    用于运行 sh 脚本文件:-
    sh script_name
    用于运行 bash 脚本文件:-
    bash script_name
  2. 如果脚本是可执行的:-
    ./script_name

NOTE:-you can check if the file is executable or not by using 'ls -a'

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

回答by benwiggy

The file extension .command is assigned to Terminal.app. Double-clicking on any .command file will execute it.

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

回答by NVRM

Little addition, to run an interpreter from the same folder, still using #!hashbangin scripts.

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

As examplea php7.2 executable copied from /usr/binis in a folder along a helloscript.

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

#!./php7.2
<?php

echo "Hello!"; 

To run it:

运行它:

./hello

Which behave just as equal as:

其行为与以下相同:

./php7.2 hello