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

时间:2022-12-25 13:56:44

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

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

6 个解决方案

#1


857  

To run a non-executable sh script, use:

要运行一个非可执行的sh脚本,请使用:

sh myscript

To run a non-executable bash script, 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 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:

当一个文件是可执行的,内核负责找出如何执行它。对于非二进制文件,这是通过查看文件的第一行来完成的。它应该包含一个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告诉内核要运行什么程序(在本例中,命令/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 sh and bash).

这意味着每个可执行的脚本都应该有一个hashbang。如果没有,你就不会告诉内核它是什么,因此内核不知道用什么程序来解释它。它可以是bash、perl、python、sh或其他东西。(在现实中,内核将经常使用用户的默认shell解释文件,这是非常危险的,因为它可能不是正确的翻译,或者它可以解析一些微妙的行为差异的,但如sh和bash)之间的情况。

A note on /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/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.

结果是内核将运行程序/bin/bash来解释脚本。不幸的是,bash并不总是默认地发送,而且它并不总是在/bin中可用。在Linux机器上,通常有很多其他POSIX机器在不同的位置上攻击,例如/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 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.

要编写一个可移植的bash脚本,我们可以不依赖于硬编码bash程序的位置。POSIX已经有一个处理该问题的机制:PATH。其思想是,您将程序安装在路径中的一个目录中,系统应该能够在您想要运行它的名称时找到您的程序。

Sadly, you cannot just do this:

遗憾的是,你不能这样做:

#!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:

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

#!/usr/bin/env bash

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.

这种方法有一个缺点:根据POSIX, hashbang可以有一个参数。在本例中,我们使用bash作为env程序的参数。这意味着我们没有剩余的空间来传递参数给bash。所以没有办法转换成#!/bin/bash -exu到这个方案。你将不得不在hashbang之后添加set -exu。

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.

这种方法还有另外一个优点:有些系统可能会使用/bin/bash,但是用户可能不喜欢它,可能会发现它是错误的或者过时的,并且可能已经在其他地方安装了自己的bash。在OS X (mac)上经常出现这样的情况,在这里,苹果公司会发布过时的/bin/bash,用户使用Homebrew之类的东西安装最新的/usr/local/bin/bash。当使用env方法进行路径搜索时,您可以考虑用户的首选项,并将首选的bash用于他的系统附带的系统。

#2


71  

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

#3


11  

For the bourne shell:

伯恩外壳:

sh myscript.sh

For bash:

bash的:

bash myscript.sh

#4


10  

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.sh can be relative, for instance . bin/script.sh runs the script.sh in the bin directory under the current directory.

注意,路径/ /脚本。例如,sh可以是相对的。bin /脚本。sh脚本运行。在当前目录下的bin目录中。

#5


0  

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. 如果脚本不能执行:-用于运行sh脚本文件:- sh script_name用于运行bash脚本文件:- bash script_name。
  3. If script is executable:-
    ./script_name
  4. 如果脚本是可执行的:- ./script_name。

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

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

#6


0  

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

文件扩展名。命令被分配到终端。应用程序。双击任何.command文件将执行它。

#1


857  

To run a non-executable sh script, use:

要运行一个非可执行的sh脚本,请使用:

sh myscript

To run a non-executable bash script, 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 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:

当一个文件是可执行的,内核负责找出如何执行它。对于非二进制文件,这是通过查看文件的第一行来完成的。它应该包含一个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告诉内核要运行什么程序(在本例中,命令/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 sh and bash).

这意味着每个可执行的脚本都应该有一个hashbang。如果没有,你就不会告诉内核它是什么,因此内核不知道用什么程序来解释它。它可以是bash、perl、python、sh或其他东西。(在现实中,内核将经常使用用户的默认shell解释文件,这是非常危险的,因为它可能不是正确的翻译,或者它可以解析一些微妙的行为差异的,但如sh和bash)之间的情况。

A note on /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/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.

结果是内核将运行程序/bin/bash来解释脚本。不幸的是,bash并不总是默认地发送,而且它并不总是在/bin中可用。在Linux机器上,通常有很多其他POSIX机器在不同的位置上攻击,例如/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 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.

要编写一个可移植的bash脚本,我们可以不依赖于硬编码bash程序的位置。POSIX已经有一个处理该问题的机制:PATH。其思想是,您将程序安装在路径中的一个目录中,系统应该能够在您想要运行它的名称时找到您的程序。

Sadly, you cannot just do this:

遗憾的是,你不能这样做:

#!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:

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

#!/usr/bin/env bash

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.

这种方法有一个缺点:根据POSIX, hashbang可以有一个参数。在本例中,我们使用bash作为env程序的参数。这意味着我们没有剩余的空间来传递参数给bash。所以没有办法转换成#!/bin/bash -exu到这个方案。你将不得不在hashbang之后添加set -exu。

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.

这种方法还有另外一个优点:有些系统可能会使用/bin/bash,但是用户可能不喜欢它,可能会发现它是错误的或者过时的,并且可能已经在其他地方安装了自己的bash。在OS X (mac)上经常出现这样的情况,在这里,苹果公司会发布过时的/bin/bash,用户使用Homebrew之类的东西安装最新的/usr/local/bin/bash。当使用env方法进行路径搜索时,您可以考虑用户的首选项,并将首选的bash用于他的系统附带的系统。

#2


71  

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

#3


11  

For the bourne shell:

伯恩外壳:

sh myscript.sh

For bash:

bash的:

bash myscript.sh

#4


10  

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.sh can be relative, for instance . bin/script.sh runs the script.sh in the bin directory under the current directory.

注意,路径/ /脚本。例如,sh可以是相对的。bin /脚本。sh脚本运行。在当前目录下的bin目录中。

#5


0  

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. 如果脚本不能执行:-用于运行sh脚本文件:- sh script_name用于运行bash脚本文件:- bash script_name。
  3. If script is executable:-
    ./script_name
  4. 如果脚本是可执行的:- ./script_name。

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

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

#6


0  

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

文件扩展名。命令被分配到终端。应用程序。双击任何.command文件将执行它。