shell 脚本语法

本文最后更新于:2022年8月5日 晚上

shell 是一种脚本语言,在Linux、Windows中都常用到,本文记录相关语法。

概述

shell 是一种脚本语言

  • 脚本:本质是一个文件,文件里面存放的是 特定格式的指令,系统可以使用脚本解析器 翻译或解析 指令 并执行(它不需要编译),是链接系统内核和用户的沟通渠道之一

  • shell 既是应用程序 又是一种脚本语言(应用程序 解析 脚本语言)
  • shell命令解析器:
  • 系统提供 shell命令解析器: sh ash bash
  • 查看自己linux系统的默认解析:echo $SHELL
1
2
$ echo $SHELL
/bin/bash
  • Windows 查看sh命令路径
1
2
> which sh
/usr/bin/sh
  • shell脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装shell命令解释器的环境下执行

基本用法

开头:#!/bin/bash

#! 用来声明脚本由什么shell解释,否则使用默认shell

调用

  • 打开终端时系统自动调用:/etc/profile~/.bashrc

    • /etc/profile :文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,系统的公共环境变量在这里设置,开始自启动的程序,一般也在这里设置

    • ~/.bashrc:用户自己的家目录中的 .bashrc,登录时会自动调用,打开任意终端时也会自动调用

  • 命令行输入 sh,可以进入shell指令状态:

1
2
3
4
>sh
sh-4.4$ echo hello world
hello world
sh-4.4$

执行

  • 运行 shell 脚本需要当前用户具有可执行权限
1
chmod +x xxxx.sh
  • 三种执行方式 (./xxx.sh bash xxx.sh . xxx.sh
执行方式 含义
./xxx.sh 优先按照 文件中#!指定的解析器解析,如果#!指定指定的解析器不存在 才会使用系统默认的解析器
bash xxx.sh 指明先用bash解析器解析 如果bash不存在,才会使用默认解析器
. xxx.sh 直接使用默认解析器解析

Windows 脚本在 Linux 运行

Win脚本在Linux执行会报错,由于换行符定义不同,需要将windows文件 转换成 unix文件

  • 可以使用 dos2unix 插件调整脚本
1
2
sudo apt-get install dos2unix
dos2unix <shell_file>
  • 也可以使用 vi,执行 :set ff=unix,将文本转为 unix 格式

变量

普通变量

定义变量
1
变量名=变量值

不能有空格

引用变量
1
$变量名
清除变量
1
unset 变量
只读变量
1
readonly 变量名=变量值
示例
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
num=8
echo 显示变量 $num
unset num
echo 清除变量 $num

-->

$ ./test.sh
显示变量 8
清除变量

交互输入变量

1
read -p "显示的字符串" [变量名1 变量名2 变量名3 ...]
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
read -p "输入三个数字: " a b c
echo $a
echo $b
echo $c

-->

$ ./test.sh
输入三个数字: 12 34 56
12
34
56

环境变量

1
env
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
env

-->

$ ./test.sh
USERDOMAIN=VVD
OS=Windows_NT
COMMONPROGRAMFILES=C:\Program Files\Common Files
PROCESSOR_LEVEL=6
PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
CommonProgramW6432=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
_=/usr/bin/env
MSYSTEM_CARCH=x86_64
DISPLAY=needs-to-be-defined
...
  • 系统变量值可以直接使用 $ 获取
1
2
3
4
5
6
7
#!/bin/bash
echo $OS

-->

$ ./test.sh
Windows_NT

注意事项

  1. 变量名只能包含英文字母下划线,不能以数字开头
  2. 等号两边不能直接接空格符,若变量中本身就包含了空格,则整个字符串都要用双引号、或单引号括起来
  3. 双引号 单引号的区别
    双引号:可以解析变量的值
    单引号:不能解析变量的值
1
2
3
4
#!/bin/bash
num=200
echo"num=$num" #Snum当成变量的值处理
echo'num=$num' #Snum当成字符串处

修改环境变量

  • 以常用的修改系统路径为例
1
export PATH=$PATH: <your_path>

预设变量

shell直接提供无需定义的变量:

变量 含义
$# 传给 shell I脚本参数的数量
$* 传给 shell 脚本参数的内容
$1、$2、$3 ... $9 运行脚本时传递给其的参数,用空格隔开
$? 命令执行后返回的状态,用于检査上一个命令执行是否正确(在 Linux中,命令退出状态为0表示该命令正确执行,任何非0值表示命令出错)。
$0 当前执行的进程名
$$ 当前进程的进程号,变量最常见的用途是用作临时文件的名字以保证临时文件不会重复

脚本标量的特殊用法

标记 含义
"" 双引号 包含的变量会被解释
'' 单引号 包含的变量会当做字符串
`(数字键1左面的反引号) 反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量
\ 转义字符 \n \t \r \a等 echo 命令需加转义并配上 -e 参数
(命令序列) 由子shel来完成,不影响当前shel中的变量
{命令序列} 在当前 shell E中执行,会影响当前变量

变量的扩展

判断变量是否存在
1
${num:-val} 如果num存在,整个表达式的值为num,否则为val
字符串的操作
  • 定义字符串
1
str="hehe: haha: xixi:lala"
  • 测量字符串的长度 ${#str}`
    1
    2
    3
    echo "str的长度为:${#str}"
    -->
    str的长度为:21
    - 从下标3为位置提取 `${str:3}`
    1
    2
    3
    echo ${str: 3}
    -->
    e: haha: xixi:lala
    - 从下标为3的位置提取长度为6的字符串 `${str: 3: 6}`
    1
    2
    3
    echo ${str: 3: 6}
    -->
    e: hah
    - 用 `#` 替换字符串`str`中的第一个`:` `${str/:/#}
1
2
3
echo ${str/:/#}
-->
hehe# haha: xixi:lala
  • # 替换字符串str中的所有: ${str//:/#}
1
2
3
echo ${str//:/#}
-->
hehe# haha# xixi#lala

条件测试

  • test命令:用于测试字符串、文件状态和数字
  • test命令有两种格式:
1
test condition 或 [ condition ]

使用方括号时,要注意在条件两边加上空格。

文件测试

  • 测试文件状态的条件表达式
参数 含义
-e 是否存在
-d 是否是目录
-f 是否是文件
-r 是否可读
-w 是否可写
-x 是否可执行
-L 是否符号连接
-c 是否字符设备
-b 是否块设备
-s 是否文件非空
  • 若返回为 True 则 $? 为0 否则非零
  • 若当前文件夹有文件 a
1
2
3
4
5
6
7
8
9
#!/bin/bash
[ -e a ]
echo $?
[ -e bbb ]
echo $?

-->
0
1

字符串操作符

操作符 含义
= 两个字符串相等
!= 两个字符串不相等
-z 是否是空字符串
-n 是否是非空字符串
  • 语法
1
2
3
4
test <op> <str>
test <str1> <op> <str2>
[ <op> <str> ]
[ <str1> <op> <str2> ]
  • 返回值为 True 则 $? 为 0,否则非零

比较运算符

运算符 英文 含义
-eq equal 相等
-ne not equal 不相等
-gt greater than 大于
-ge greater equal 大于等于
-le less equal 小于等于
-lt less than 小于
  • 返回值为 True 则 $? 为 0,否则非零

逻辑运算符

运算符 英文 含义
&&-a and 与操作
||-o or 或操作
! not 非操作

控制语句

if

1
2
3
4
5
6
7
if [条件1]; then
执行第一段程序
elif [条件2];then
执行第二段程序
else
执行第三段程序
fi

case

1
2
3
4
5
6
7
8
case $变量 in
变量1 | 变量2 | 变量3 ... )
执行代码段一
变量4 | 变量5 ... )
执行代码段二
*)
执行默认代码段
esac

for

1
2
3
4
5
6
7
8
9
10
11
for ((初始值; 条件值; 执行步阶))
do
代码段
done

-->

for ((i=0; i<=100; i++))
do
sum=$sum+$i
done
1
2
3
4
5
6
7
8
9
10
11
for var in con1 con2 con3 ...
do
代码段
done

-->

for i in 1 2 3 4 5
do
sum=$sum+$i
done

while

  • condition 为 True 时执行代码段,否则跳出 while 循环
1
2
3
4
while [ <condition> ]
do
代码段
done

until

  • condition 为 True 时跳出 until 循环,否则执行代码段
1
2
3
4
until [ <condition> ]
do
代码段
done

break

  • 跳出循环体

continue

  • 跳出当前循环步骤,立即开启下一次循环

函数

定义函数

1
2
3
函数名 () {
代码段
}
1
2
3
function 函数名(){
代码段
}

所有函数在使用前必须定义,必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用

调用函数

1
函数名  para1 para2 ...
  • 使用参数同在一般脚本中使用参数时相同,

    $1, $2, $3

  • 可以使用 return 返回值

  • 默认无错误返回 0 ,否则返回 1

导入函数

  • fun.sh 中定义的函数可以在其他sh文件中引用:
1
source fun.sh
  • 之后可以使用 fun.sh 文件中定义的函数

参考资料


shell 脚本语法
https://www.zywvvd.com/notes/coding/shell/shell-usage/shell-usage/
作者
Yiwei Zhang
发布于
2021年11月11日
许可协议