一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
wiki
在初次接触 shell 脚本时,对于其中的一些符号的约定,总是有些迷惑,当遇到时就纪录下来,因此比较零碎。
1. 脚本传参
在 shell 脚本中,可以直接使用如下的预置符号,直接获取传入的参数,以及一些脚本元数据
$0: 脚本本身文件名称$1: 命令行第一个参数,$2为第二个,以此类推$*: 所有参数列表$@: 所有参数列表$#: 参数个数$$: 脚本运行时的PID$?: 脚本退出码
2. ∗ 与 @ 的区别
两者均表示获取全部的参数列表,但使用时还有一些区别,二者没有被引号括起来时行为一致,当一旦在被括号括起来时:
"$*": 将所有传参看成一个参数"$@": 将每个参数都看作独立的
我们编写脚本进行说明:
#!/bin/bash
echo "Show param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "Show param from \"\$@\""
for var in "$@"
do
echo "$var"
done
调用命令为 sh test_param.sh 1 2 3,其结果为
Show param from "$*"
1 2 3
Show param from "$@"
1
2
3
3. ${} 变量替换
$var 与 ${var} 本身是没有区别的,但是用 ${} 会比较精确的界定变量名称的范围。
A=Linux
echo $AB #表示变量AB
echo ${A}B #表示变量A后连接着B,即LinuxB
4. $() 、 $(()) 和反引号(``)
$(): 等同于反引号(``) ,但并不是所有的类 unix 系统都支持$()这种方式,但反引号是肯定支持的$(()): 表示进行数字运算
a=3;b=2;c=5
echo $((a+b*c)) # 13
5. 单引号与双引号
- 单引号属于强引用,它会忽略所有被引起来的字符的特殊处理,被引用起来的字符会被原封不动的使用,单引号字串中不能出现单引号(对单引号使用转义符后也不行)
- 双引号属于弱引用,它会对一些被引起来的字符进行特殊处理
[root@host ]$ echo '$(echo hello world)'
[root@host ]$ $(echo hello world)
[root@host ]$ echo "$(echo hello world)"
[root@host ]$ hello world
6. BASH_SOURCE 与 dirname
BASH_SOURCE[0] : 等价于 BASH_SOURCE,取得当前执行的 shell 文件所在的路径及文件名
dirname : 去除文件名中的非目录部分,仅显示与目录有关的部分
如 /home/abc/test.sh 内容如下:
#!/bin/bash
echo "${BASH_SOURCE[0]}"
echo "${BASH_SOURCE}"
echo "$(dirname "${BASH_SOURCE[0]}")"
echo "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
若在目录 /home 下执行 sh ./abc/test.sh,输出为:
abc/test.sh
abc/test.sh
abc/
/home/abc
7. SHLVL
SHLVL代表shell打开的深度,进程第一次打开shell时$SHLVL=1,然后在此shell中再打开一个shell时$SHLVL=2。
8. 注意
${BASH_SOURCE-$0}:获取当前执行的脚本文件的全路径。- 获取当前执行脚本名,如果是
sh或者./的运行方式,直接使用$0,如果是source的方式运行,$0就变成了-bash了。因为source命令,不再产生新的 shell,而是在当前 shell 下执行一切命令。此时需要使用$BASH_SOURCE。