shell 是一种脚本语言,在Linux、Windows中都常用到,本文记录相关语法。
概述
shell 是一种脚本语言
- 脚本:本质是一个文件,文件里面存放的是 特定格式的指令,系统可以使用脚本解析器 翻译或解析 指令 并执行(它不需要编译),是链接系统内核和用户的沟通渠道之一
- shell 既是应用程序 又是一种脚本语言(应用程序 解析 脚本语言)
- shell命令解析器:
- 系统提供 shell命令解析器:
sh
ash
bash
- 查看自己linux系统的默认解析:echo $SHELL
$ echo $SHELL
/bin/bash
- Windows 查看sh命令路径
> which sh
/usr/bin/sh
- shell脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装shell命令解释器的环境下执行
基本用法
开头:#!/bin/bash
#!
用来声明脚本由什么shell解释,否则使用默认shell
调用
- 打开终端时系统自动调用:
/etc/profile
或~/.bashrc
-
/etc/profile
:文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,系统的公共环境变量在这里设置,开始自启动的程序,一般也在这里设置 -
~/.bashrc
:用户自己的家目录中的.bashrc
,登录时会自动调用,打开任意终端时也会自动调用
-
- 命令行输入
sh
,可以进入shell指令状态:
>sh
sh-4.4$ echo hello world
hello world
sh-4.4$
执行
- 运行 shell 脚本需要当前用户具有可执行权限
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
插件调整脚本
sudo apt-get install dos2unix
dos2unix <shell_file>
- 也可以使用 vi,执行
:set ff=unix
,将文本转为 unix 格式
变量
普通变量
定义变量
代码语言:javascript复制变量名=变量值
不能有空格
引用变量
代码语言:javascript复制$变量名
清除变量
代码语言:javascript复制unset 变量
只读变量
代码语言:javascript复制readonly 变量名=变量值
示例
代码语言:javascript复制#!/bin/bash
num=8
echo 显示变量 $num
unset num
echo 清除变量 $num
-->
$ ./test.sh
显示变量 8
清除变量
交互输入变量
代码语言:javascript复制read -p "显示的字符串" [变量名1 变量名2 变量名3 ...]
代码语言:javascript复制#!/bin/bash
read -p "输入三个数字: " a b c
echo $a
echo $b
echo $c
-->
$ ./test.sh
输入三个数字: 12 34 56
12
34
56
环境变量
代码语言:javascript复制env
代码语言:javascript复制#!/bin/bash
env
-->
$ ./test.sh
USERDOMAIN=VVD
OS=Windows_NT
COMMONPROGRAMFILES=C:Program FilesCommon Files
PROCESSOR_LEVEL=6
PSModulePath=C:Program FilesWindowsPowerShellModules;C:Windowssystem32WindowsPowerShellv1.0Modules
CommonProgramW6432=C:Program FilesCommon Files
CommonProgramFiles(x86)=C:Program Files (x86)Common Files
_=/usr/bin/env
MSYSTEM_CARCH=x86_64
DISPLAY=needs-to-be-defined
...
- 系统变量值可以直接使用
$
获取
#!/bin/bash
echo $OS
-->
$ ./test.sh
Windows_NT
注意事项:
- 变量名只能包含英文字母下划线,不能以数字开头
- 等号两边不能直接接空格符,若变量中本身就包含了空格,则整个字符串都要用双引号、或单引号括起来
- 双引号 单引号的区别 双引号:可以解析变量的值 单引号:不能解析变量的值
#!/bin/bash
num=200
echo"num=$num" #Snum当成变量的值处理
echo'num=$num' #Snum当成字符串处
修改环境变量
- 以常用的修改系统路径为例
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中执行,会影响当前变量 |
变量的扩展
判断变量是否存在
代码语言:javascript复制${num:-val} 如果num存在,整个表达式的值为num,否则为val
字符串的操作
- 定义字符串
str="hehe: haha: xixi:lala"
测量字符串的长度
代码语言:javascript复制echo "str的长度为:${#str}"
-->
str的长度为:21
- 从下标3为位置提取 `${str:3}`
代码语言:javascript复制echo ${str: 3}
-->
e: haha: xixi:lala
- 从下标为3的位置提取长度为6的字符串 `${str: 3: 6}`
代码语言:javascript复制echo ${str: 3: 6}
-->
e: hah
- 用
#
替换字符串str
中的所有:
${str//:/#}
echo ${str/:/#}
-->
hehe# haha: xixi:lala
条件测试
- test命令:用于测试字符串、文件状态和数字
- test命令有两种格式:
test condition 或 [ condition ]
使用方括号时,要注意在条件两边加上空格。
文件测试
- 测试文件状态的条件表达式
参数 | 含义 |
---|---|
-e | 是否存在 |
-d | 是否是目录 |
-f | 是否是文件 |
-r | 是否可读 |
-w | 是否可写 |
-x | 是否可执行 |
-L | 是否符号连接 |
-c | 是否字符设备 |
-b | 是否块设备 |
-s | 是否文件非空 |
- 若返回为 True 则
$?
为0 否则非零 - 若当前文件夹有文件
a
#!/bin/bash
[ -e a ]
echo $?
[ -e bbb ]
echo $?
-->
0
1
字符串操作符
操作符 | 含义 |
---|---|
= | 两个字符串相等 |
!= | 两个字符串不相等 |
-z | 是否是空字符串 |
-n | 是否是非空字符串 |
- 语法
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
代码语言:javascript复制if [条件1]; then
执行第一段程序
elif [条件2];then
执行第二段程序
else
执行第三段程序
fi
case
代码语言:javascript复制case $变量 in
变量1 | 变量2 | 变量3 ... )
执行代码段一
变量4 | 变量5 ... )
执行代码段二
*)
执行默认代码段
esac
for
代码语言:javascript复制for ((初始值; 条件值; 执行步阶))
do
代码段
done
-->
for ((i=0; i<=100; i ))
do
sum=$sum $i
done
代码语言:javascript复制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 循环
while [ <condition> ]
do
代码段
done
until
- condition 为 True 时跳出 until 循环,否则执行代码段
until [ <condition> ]
do
代码段
done
break
- 跳出循环体
continue
- 跳出当前循环步骤,立即开启下一次循环
函数
定义函数
代码语言:javascript复制函数名 () {
代码段
}
代码语言:javascript复制function 函数名(){
代码段
}
所有函数在使用前必须定义,必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用
调用函数
代码语言:javascript复制函数名 para1 para2 ...
- 使用参数同在一般脚本中使用参数时相同, 1, 2,
- 可以使用 return 返回值
- 默认无错误返回 0 ,否则返回 1
导入函数
- 在
fun.sh
中定义的函数可以在其他sh文件中引用:
source fun.sh
- 之后可以使用
fun.sh
文件中定义的函数
参考资料
- https://www.jb51.net/article/185260.htm