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

P-A*_*P-A 496 unix linux macos bash shell

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

lhu*_*ath 922

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

sh myscript
Run Code Online (Sandbox Code Playgroud)

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

bash myscript
Run Code Online (Sandbox Code Playgroud)

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

/foo/bar
/bin/bar
./bar
Run Code Online (Sandbox Code Playgroud)

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

chmod +x bar
./bar
Run Code Online (Sandbox Code Playgroud)

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

#! /usr/bin/env bash
Run Code Online (Sandbox Code Playgroud)

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

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

关于 /usr/bin/env

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

#!/bin/bash
Run Code Online (Sandbox Code Playgroud)

结果是内核将运行程序/bin/bash来解释脚本.不幸的是,bash默认情况下并不总是发货,并且它并不总是可用/bin.在Linux机器上通常是,有一系列其他POSIX机器bash在不同位置的船舶,如/usr/xpg/bin/bash/usr/local/bin/bash.

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

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

#!bash
Run Code Online (Sandbox Code Playgroud)

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

#!/usr/bin/env bash
Run Code Online (Sandbox Code Playgroud)

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

这种方法还有一个好处:一些系统可能与船舶/bin/bash,但用户可能不喜欢它,会发现它是越野车或过时,并且可能已经安装了自己的bash其他地方.在OS X(Macs)上经常出现这种情况,其中Apple发布了过时版本/bin/bash,用户/usr/local/bin/bash使用Homebrew之类的东西安装了最新版本.当您使用env执行PATH搜索的方法时,您会考虑用户的偏好并使用他喜欢的bash而不是他的系统附带的bash.

  • 感谢您抽出宝贵时间为一个简单的问题写一个好的答案. (63认同)
  • @stefmikhail:使用哪个shell解释器*调用*脚本并不重要,你应该使用`#!/ usr/bin/env zsh` if(且仅当)*脚本内部的代码*应该由Z shell执行. (6认同)
  • 如果我使用`zsh`作为我的shell,我会使用`hashbang``#!/ usr/bin/env zsh`? (5认同)
  • @Carpetsmoker 这是正确的,不仅限于 hashbang。bash 脚本应始终使用 UNIX 行结尾,否则每个命令的最后一个参数都会附加一个 \r,就像 hashbang 命令名称一样。 (2认同)

P-A*_*P-A 80

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

sh file.sh

bash file.sh
Run Code Online (Sandbox Code Playgroud)

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

chmod +x file.sh
Run Code Online (Sandbox Code Playgroud)

现在运行.sh文件如下:

./file.sh
Run Code Online (Sandbox Code Playgroud)


小智 15

对于bourne shell:

sh myscript.sh
Run Code Online (Sandbox Code Playgroud)

对于bash:

bash myscript.sh
Run Code Online (Sandbox Code Playgroud)


Cha*_*ens 10

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

. /path/to/script.sh
Run Code Online (Sandbox Code Playgroud)

要么

source /path/to/script.sh
Run Code Online (Sandbox Code Playgroud)

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

  • 在采用相关路径名进行采购或打点时要非常谨慎.你应该**始终用./启动它们.如果你不这样做,并且相对路径名不包含任何斜杠,你将在PATH中找到一些东西,然后在当前目录中的东西!滥用非常危险. (6认同)

Vin*_*ain 5

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

  1. 如果脚本不可执行:-
    对于运行 sh 脚本文件:-
    sh script_name
    对于运行 bash 脚本文件:-
    bash script_name
  2. 如果脚本可执行:-
    ./script_name

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