# sh 脚本
sh 脚本即 shell 脚本,就是由 Shell 命令组成的执行文件。我们可以通过shell命令来操作和控制操作系统,比如Linux中的 Shell 命令就包括ls、cd、pwd等等。shell 脚本和 linux 命令的区别是 shell 是一个用 C 语言编写的程序,既是一种命令语言,又是一种程序设计语言,相当于有了一定的逻辑和过程。
# Shell 变量
Shell 变量分为系统变量和自定义变量。系统变量有$HOME、$PWD、$USER等。自定义变量又分为局部变量和环境变量(全局变量)
- 显示所有变量:
set
- 删除变量:
unset 变量名
- 使用变量:
$变量名
、${变量名}
- 打印变量:
echo ${变量名}
# 局部变量
- 定义变量:
变量名=变量值
,等号两侧不能有空格,变量名一般习惯用大写。 - 声明静态变量:
readonly 变量名=变量值
,静态变量不能 unset。
# 环境变量(全局变量)
与局部变量的区别是子 shell 继承可以当前父 shell 的环境变量,并能一直传承下去
export 变量名=变量值
,将 Shell 变量输出为环境变量。source 配置文件路径
,让修改后的配置信息立即生效。echo $变量名
,检查环境变量是否生效
export var=1 # 注意等号两边不能有空格
echo ${var}
bash # 开启子 shell
echo ${var} # 1
# path 环境变量
首先介绍一下 which 命令,它用于查找某个命令所在的绝对路径。
which node #/usr/local/bin/node
which npm #/usr/local/bin/npm
which rm #/bin/rm
为什么前面在使用 rm、node、npm 等命令时,无论当前位于哪个目录,都可以直接使用,而无需指明命令的执行文件所在的位置,这是 PATH 环境变量在起作用。
echo $PATH
# /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin
PATH 环境变量的内容是由一堆目录组成的,各目录之间用冒号“:”隔开。当执行某个命令时,Linux 会依照 PATH 中包含的目录依次搜寻该命令的可执行文件。
export APATH = /user/a/bin
export PATH=$APATH:$PATH
# 在原有的 path 基础上添加新的目录
# 注意,这种方式只是临时有效,一旦退出下次再登陆的时候,$PATH 就恢复成了默认值。
# 位置参数变量
- $n :$0 代表命令本身、$1-$9 代表第1到9个参数,10以上参数用花括号,如 ${10}。
- $* :传递给脚本或者函数的所有参数,且把所有参数看成一个整体输出。
- $@ :传递给脚本或者函数的所有参数,且把每个参数区分对待输出。
- $# :所有参数个数。
# test.sh 输出各个参数
echo $0 $1 $2
echo $* test.sh
echo $@
echo 参数个数=$#
chmod +x test.sh # 赋予文件的执行权限
./test.sh 1 2 3 4
# ./test.sh 1 2
# 1 2 3 4 test.sh
# 1 2 3 4
# 参数个数=4
将命令行参数传递到脚本,再传递到函数内:
# test.sh
function main() {
echo $@ # 接收函数传入参数
}
main $@ # 接收命令行传入参数
./test.sh 123
# 预定义变量
- $$ :当前进程的 PID 进程号。
- $! :后台运行的最后一个进程的 PID 进程号。
- $? :最后一次执行的命令的返回状态,0为执行正确,非0执行失败。
npm install # 假如执行了安装依赖的命令并报错
echo $? # 则会打印非0,代表执行失败
# 括号
# 双中括号
- [[是 bash 程序语言的关键字。并不是一个命令,[[ ]] 结构比[ ]结构更加通用。在 [[ 和 ]] 之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。
- 支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。
- 使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于 [[ ]] 条件判断结构中,但是如果出现在 [ ] 结构中的话会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]]。
- bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。
# 判断上一条命令返回状态是否为 0(正确),为 0 则输出
[[ $? = 0 ]] && echo $?