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
How to run a shell script on a Unix console or Mac terminal?
提问by P-A
I know it, forget it and relearn it again. Time to write it down.
我知道它,忘记它并重新学习它。是时候写下来了。
采纳答案by lhunath
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 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/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
注意事项 /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 机器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 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
. 这个想法是您将程序安装在其中一个目录中,PATH
并且当您想按名称运行程序时,系统应该能够找到您的程序。
Sadly, you cannotjust 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:
内核不会(有些人可能)会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 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
成这个方案。你必须把它放在set -exu
hashbang之后。
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 (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.sh
can be relative, for instance . bin/script.sh
runs the script.sh
in the bin
directory under the current directory.
注意/path/to/script.sh
可以是相对的,比如在当前目录下的目录下. bin/script.sh
运行。script.sh
bin
回答by Vineet Jain
First, give permission for execution:-chmod +x script_name
首先,授予执行权限:-chmod +x script_name
- If script is not executable:-
For running sh script file:-sh script_name
For running bash script file:-bash script_name
- If script is executable:-
./script_name
- 如果脚本不可执行:-
用于运行 sh 脚本文件:-sh script_name
用于运行 bash 脚本文件:-bash script_name
- 如果脚本是可执行的:-
./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