admin管理员组

文章数量:1622629

Bash shebang [`#!`]

  • 1. Bash
  • 2. shebang
    • 2.1. Syntax
    • 2.2. `env` (user command) - run a program in a modified environment (在修改后的环境中运行命令)
    • 2.3. Examples
  • 3. yongqiang
  • 4. GNU Bourne-Again SHell - bash
  • References

1. Bash

The Bourne shell (sh) is a shell command-line interpreter for computer operating systems.

Bash is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell (sh).
Bash 是一个命令处理器,通常运行于文本窗口中,并能执行用户直接输入的命令。

The shell’s name is an acronym for Bourne Again Shell, a pun on the name of the Bourne shell (sh) that it replaces and the notion of being “born again”.
Bash 是 Bourne shell 的后继兼容版本与开放源代码版本,它的名称来自 Bourne shell (sh) 的一个双关语 Bourne Again SHell。

pun [pʌn]:n. 双关语 vi. 使用双关语

操作系统支持 Shell 的类型:

(base) yongqiang@yongqiang:~$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
/usr/bin/tmux
/usr/bin/screen
(base) yongqiang@yongqiang:~$

Bash 的绝对路径:

(base) yongqiang@yongqiang:~$ which bash
/bin/bash
(base) yongqiang@yongqiang:~$

2. shebang

In computing, a shebang is the character sequence consisting of the characters number sign and exclamation mark (#!) at the beginning of a script. It is also called sharp-exclamation, sha-bang, hashbang, pound-bang, or hash-pling.
shebang 是一个由井号和叹号构成的字符序列 #!,其出现在文本文件的第一行的前两个字符。

The shebang line is usually ignored by the interpreter, because the # character is a comment marker in many scripting languages; some language interpreters that do not use the hash mark to begin comments still may ignore the shebang line in recognition of its purpose.
由于 # 符号在许多脚本语言中都是注释标识符,shebang 的内容会被这些脚本解释器自动忽略。在 # 字符不是注释标识符的语言中,解释器也可能忽略以 #! 开头的首行内容,以提供与 shebang 的兼容性。

The name shebang for the distinctive two characters may have come from an inexact contraction of SHArp bang or haSH bang, referring to the two typical Unix names for them. Another theory on the sh in shebang is that it is from the default shell sh, usually invoked with shebang.

shebang 的名字来自于 SHArp bang or haSH bang 的缩写,指代 shebang#! 两个符号的典型 Unix 名称。在 Unix 术语中,井号通常称为 sharp, hash or mesh;而叹号则常常称为 bang。

contraction [kənˈtrækʃn]:n. 收缩,缩小,(肌肉的) 收缩,挛缩,子宫收缩,词的缩约形式
bang [bæŋ]:v. 猛敲,砸,(把 ...) 砰的关上,猛摔,砰地一扔,碰撞,和 (女性) 性交 n. 突然的巨响,(对身体部位的) 猛撞,猛敲,猛击,叹号 adv. 正好,完全地 int. (表示枪声等巨响) 砰

2.1. Syntax

The form of a shebang interpreter directive is as follows:

#!interpreter [optional-arg]

in which interpreter is generally an absolute path to an executable program. The optional argument is a string representing a single argument. White space after #! is optional.
shebang#! 开头,即井号和叹号。在 #! 开头字符之后,可以有 0 个,1 个或多个空白字符,后接解释器的绝对路径,用于调用解释器。

#! 字符称为 shebang,后接脚本解释器,脚本解释器一般是 /bin/sh/bin/bash

#!/bin/sh
或者
#!/bin/bash

Interpreter directives allow scripts and data files to be used as commands, hiding the details of their implementation from users and other programs, by removing the need to prefix scripts with their interpreter on the command line.
解释器指令允许脚本和数据文件充当系统命令,无需在调用时由用户指定解释器,从而对用户和其它程序隐藏其实现细节。

exclamation [.eksklə'meɪʃ(ə)n]:n. 感叹,感叹词,感叹语

#! is followed by /usr/bin/env, followed by the desired command without full path, as in this example:

#!/usr/bin/env sh

This mostly works because the path /usr/bin/env is commonly used for the env utility, and it invokes the first sh found in the user’s $PATH, typically /bin/sh.
使用 #!/usr/bin/env sh 脚本解释器名称是一种常见的在不同平台上都能正确找到解释器的办法。

如果脚本解释器不放在目录 /bin,则脚本就无法执行了。为了保险起见,可以写成 #!/usr/bin/env bash,使用 env 命令 (总是在 /usr/bin 目录),返回 Bash 可执行文件的位置。

2.2. env (user command) - run a program in a modified environment (在修改后的环境中运行命令)

env 命令用于显示系统中已存在的环境变量,以及在定义的环境中执行指令。env 命令只使用 - 作为参数选项时,隐藏了选项 -i 的功能。若没有设置任何选项和参数时,则直接显示当前的环境变量。

environment,env:环境变量

env 命令总是指向 /usr/bin/env 文件,/usr/bin/env 二进制文件总是在目录 /usr/bin/

#!/usr/bin/env NAME 的意思是,让 shell 查找 $PATH 环境变量里面第一个匹配的 NAME。如果不知道某个命令的具体路径,或者希望兼容其他用户的机器,请使用这种写法。

#!/usr/bin/env bash 返回 bash 可执行文件的位置,前提是 bash 的路径是在 $PATH 里面。

env 命令的参数如下:

-i, --ignore-environment: start with an empty environment (开始一个新的空的环境)
-u, --unset=NAME: remove variable from the environment (从当前环境中删除指定的变量)
-C, --chdir=DIR: change working directory to DIR
-0, --null: end each output line with NUL, not newline
--help: display this help and exit
--version: output version information and exit

  1. 系统的环境变量
(base) yongqiang@yongqiang:~$ env
...
CONDA_EXE=/home/yongqiang/miniconda3/bin/conda
CONDA_PREFIX=/home/yongqiang/miniconda3
USER=yongqiang
PWD=/home/yongqiang
HOME=/home/yongqiang
CONDA_PYTHON_EXE=/home/yongqiang/miniconda3/bin/python
NAME=yongqiang
...
(base) yongqiang@yongqiang:~$

(base) yongqiang@yongqiang:~$ echo ${NAME}
yongqiang
(base) yongqiang@yongqiang:~$

(base) yongqiang@yongqiang:~$ echo ${SHELL}
/bin/bash
(base) yongqiang@yongqiang:~$

(base) yongqiang@yongqiang:~$ env | egrep -i "pwd|hosttype"
HOSTTYPE=x86_64
PWD=/home/yongqiang
(base) yongqiang@yongqiang:~$
  1. 从当前环境中删除指定的变量
$ env -u USER
  1. 定义指定的环境变量

在新的环境中定义变量,定义多个变量用空格隔开,格式为“变量名=值”。临时设置环境变量,常用于设置环境变量 PATH

$ env NAME=root
  1. 新建一个不带任何环境变量的 shell
$ env -i /bin/sh

2.3. Examples

Some typical shebang lines:

  • #!/bin/sh - Execute the file using the Bourne shell, or a compatible shell, assumed to be in the /bin directory
  • #!/bin/bash - Execute the file using the Bash shell
  • #!/usr/bin/pwsh - Execute the file using PowerShell
  • #!/usr/bin/env python3 - Execute with a Python interpreter, using the env program search path to find it
  • #!/bin/false - Do nothing, but return a non-zero exit status, indicating failure.

For example, if a script is named with the path path/to/script, and it starts with the following line, #!/bin/sh, then the program loader is instructed to run the program /bin/sh, passing path/to/script as the first argument.
#!/bin/sh 作为行开头,程序加载器运行程序 /bin/sh,传递 path/to/script 作为第一个参数。

3. yongqiang

脚本 (script) 是包含一系列命令的文本文件。shell 读取脚本,依次执行里面的所有命令,脚本的好处是可以重复使用。

  1. 工作区 /home/yongqiang/bash_work
(base) yongqiang@yongqiang:~$ mkdir bash_work
(base) yongqiang@yongqiang:~$ cd bash_work/
  1. touch 命令创建一个空文件 bash_script.sh
(base) yongqiang@yongqiang:~/bash_work$ touch bash_script.sh
(base) yongqiang@yongqiang:~/bash_work$ ll
total 0
drwxr-xr-x 1 yongqiang yongqiang 512 Apr 23 22:18 ./
drwxr-xr-x 1 yongqiang yongqiang 512 Apr 23 22:16 ../
-rw-r--r-- 1 yongqiang yongqiang   0 Apr 23 22:18 bash_script.sh
(base) yongqiang@yongqiang:~/bash_work$
  1. #! 指定解释器的绝对路径 /bin/bash
(base) yongqiang@yongqiang:~/bash_work$ vim ./bash_script.sh
(base) yongqiang@yongqiang:~/bash_work$
(base) yongqiang@yongqiang:~/bash_work$ cat ./bash_script.sh
#!/bin/bash

echo "Yongqiang Cheng!"

(base) yongqiang@yongqiang:~/bash_work$
  1. 添加执行权限并执行

阅读权限 (r):允许查看文件内容
写入权限 (w):允许修改文件内容
执行权限 (x):允许运行编程文件或脚本

脚本需要有执行权限,才可以执行。脚本的权限通常设为 755 (拥有者有所有权限,其他人有读和执行权限) 或者 700 (只有拥有者可以执行)。

# 所有用户赋予执行权限
$ chmod a+x bash_script.sh

# 所有用户赋予读权限和执行权限
$ chmod a+rx bash_script.sh
$ chmod 755 bash_script.sh

# 脚本拥有者赋予读权限和执行权限
$ chmod u+rx bash_script.sh
(base) yongqiang@yongqiang:~/bash_work$ chmod a+x ./bash_script.sh
(base) yongqiang@yongqiang:~/bash_work$
(base) yongqiang@yongqiang:~/bash_work$ ./bash_script.sh
Yongqiang Cheng!
(base) yongqiang@yongqiang:~/bash_work$

shebang 行不是必需的,但是建议加上。如果缺少 shebang 行,就需要手动将脚本传给解释器。脚本是 bash_script.sh,有 shebang 行的时候,可以直接调用执行。

$ ./bash_script.sh

bash_script.sh 是脚本文件名,通常使用 .sh 后缀名,不过这不是必需的。

如果没有 shebang 行,就只能手动将脚本传给解释器来执行。下面的执行方式不需要在第一行指定解释器信息。

(base) yongqiang@yongqiang:~/bash_work$ /bin/bash bash_script.sh
Yongqiang Cheng!
(base) yongqiang@yongqiang:~/bash_work$
$ /bin/sh ./bash_script.sh
或者
$ bash ./bash_script.sh

脚本调用时,需要指定脚本的路径 (/path/bash_script.sh)。如果将脚本放在环境变量 $PATH 指定的目录中,就不需要指定路径了。因为 Bash 会自动到这些目录中,寻找是否存在同名的可执行文件。在主目录新建一个 ~/bin 子目录,存放可执行脚本,然后把 ~/bin 加入 $PATH

export PATH=$PATH:~/bin

上面命令改变环境变量 $PATH,将 ~/bin 添加到 $PATH 的末尾。将这一行加到 ~/.bashrc 文件里面,重新加载一次 .bashrc,确保配置生效。

$ source ~/.bashrc

不管在什么目录,直接输入脚本文件名,脚本就会执行。下面的命令没有指定脚本路径,可以正常执行,因为 bash_script.sh$PATH 指定的目录中。

$ bash_script.sh

4. GNU Bourne-Again SHell - bash

GNU Bash
https://www.gnu/software/bash/

GNU Bash manual
https://www.gnu/software/bash/manual/

Bash Reference Manual
https://www.gnu/software/bash/manual/bash.html

GNU Manuals Online
https://www.gnu/manual/

The GNU Bourne-Again SHell
https://tiswww.case.edu/php/chet/bash/bashtop.html

Bash is the GNU Project’s shell - the Bourne Again SHell. This is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and the C shell (csh). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard.

General Commands Manual - BASH

(base) yongqiang@yongqiang:~$ info bash
...
(base) yongqiang@yongqiang:~$ man bash
...
(base) yongqiang@yongqiang:~$ bash --help
GNU bash, version 4.4.20(1)-release-(x86_64-pc-linux-gnu)
Usage:  bash [GNU long option] [option] ...
        bash [GNU long option] [option] script-file ...
GNU long options:
        --debug
        --debugger
        --dump-po-strings
        --dump-strings
        --help
        --init-file
        --login
        --noediting
        --noprofile
        --norc
        --posix
        --rcfile
        --restricted
        --verbose
        --version
Shell options:
        -ilrsD or -c command or -O shopt_option         (invocation only)
        -abefhkmnptuvxBCHP or -o option
Type `bash -c "help set"' for more information about shell options.
Type `bash -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.

bash home page: <http://www.gnu/software/bash>
General help using GNU software: <http://www.gnu/gethelp/>
(base) yongqiang@yongqiang:~$
(base) yongqiang@yongqiang:~$ ls -l /usr/share/doc/bash/
total 84
-rw-r--r-- 1 root root  7853 Sep  8  2016 COMPAT.gz
-rw-r--r-- 1 root root  2921 Feb 18  1999 INTRO.gz
-rw-r--r-- 1 root root 27983 Aug 23  2016 NEWS.gz
-rw-r--r-- 1 root root  3702 May 10  2016 POSIX.gz
-rw-r--r-- 1 root root  1693 Jun  7  2019 RBASH
-rw-r--r-- 1 root root  3839 Jun  7  2019 README
-rw-r--r-- 1 root root  1919 Jun  7  2019 README.Debian.gz
-rw-r--r-- 1 root root  1105 Jun  7  2019 README.abs-guide
-rw-r--r-- 1 root root  3021 Jun  7  2019 READMEmands.gz
lrwxrwxrwx 1 root root    31 Apr  2  2018 README.md.bash_completion.gz -> ../bash-completion/README.md.gz
-rw-r--r-- 1 root root  1357 Jun  7  2019 changelog.Debian.gz
-rw-r--r-- 1 root root 10231 Jun  7  2019 copyright
-rw-r--r-- 1 root root   727 Jun  7  2019 inputrc.arrows
(base) yongqiang@yongqiang:~$

References

[1] Yongqiang Cheng, https://yongqiang.blog.csdn/
[2] Bourne shell, https://en.wikipedia/wiki/Bourne_shell
[3] Bash (Unix shell), https://en.wikipedia/wiki/Bash_(Unix_shell)
[4] Shebang (Unix), https://en.wikipedia/wiki/Shebang_(Unix)
[5] Bash 教程总览, https://www.w3cschool/bashshell/
[6] Bash 脚本教程, https://wangdoc/bash/index.html

本文标签: bashshebang