持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
tags: [Coding, Shell] categories: [Coding, Shell]
shell 是一种脚本语言,在Linux、Windows中都常用到,本文记录相关语法。
概述
shell 是一种脚本语言
- 脚本:本质是一个文件,文件里面存放的是 特定格式的指令,系统可以使用脚本解析器 翻译或解析 指令 并执行(它不需要编译),是链接系统内核和用户的沟通渠道之一
- shell 既是应用程序 又是一种脚本语言(应用程序 解析 脚本语言)
- shell命令解析器:
- 系统提供 shell命令解析器:
shashbash - 查看自己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.shbash 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 格式
变量
普通变量
定义变量
变量名=变量值
不能有空格
引用变量
$变量名
清除变量
unset 变量
只读变量
readonly 变量名=变量值
示例
#!/bin/bash
num=8
echo 显示变量 $num
unset num
echo 清除变量 $num
-->
$ ./test.sh
显示变量 8
清除变量
交互输入变量
read -p "显示的字符串" [变量名1 变量名2 变量名3 ...]
#!/bin/bash
read -p "输入三个数字: " a b c
echo $a
echo $b
echo $c
-->
$ ./test.sh
输入三个数字: 12 34 56
12
34
56
环境变量
env
#!/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
...
- 系统变量值可以直接使用
$获取
#!/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中执行,会影响当前变量 |
变量的扩展
判断变量是否存在
${num:-val} 如果num存在,整个表达式的值为num,否则为val
字符串的操作
- 定义字符串
str="hehe: haha: xixi:lala"
- 测量字符串的长度
${#str}
echo "str的长度为:${#str}"
-->
str的长度为:21
- 从下标3为位置提取
${str:3}
echo ${str: 3}
-->
e: haha: xixi:lala
- 从下标为3的位置提取长度为6的字符串
${str: 3: 6}
echo ${str: 3: 6}
-->
e: hah
- 用
#替换字符串str中的第一个:${str/:/#}
echo ${str/:/#}
-->
hehe# haha: xixi:lala
- 用
#替换字符串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
if [条件1]; then
执行第一段程序
elif [条件2];then
执行第二段程序
else
执行第三段程序
fi
case
case $变量 in
变量1 | 变量2 | 变量3 ... )
执行代码段一
变量4 | 变量5 ... )
执行代码段二
*)
执行默认代码段
esac
for
for ((初始值; 条件值; 执行步阶))
do
代码段
done
-->
for ((i=0; i<=100; i++))
do
sum=$sum+$i
done
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
- 跳出当前循环步骤,立即开启下一次循环
函数
定义函数
函数名 () {
代码段
}
function 函数名(){
代码段
}
所有函数在使用前必须定义,必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用
调用函数
函数名 para1 para2 ...
-
使用参数同在一般脚本中使用参数时相同,
$1,$2,$3.... -
可以使用 return 返回值
-
默认无错误返回 0 ,否则返回 1
导入函数
- 在
fun.sh中定义的函数可以在其他sh文件中引用:
source fun.sh
- 之后可以使用
fun.sh文件中定义的函数