Shell 脚本语法
- Shell 解释器
名称 | 路径 | 简介 |
---|---|---|
Bourne Shell | /usr/bin/sh或/bin/sh | Bourne shell是AT&T开发的原始UNIX shell以其开发人员Stephen Bourne命名,Bourne shell也以其程序名sh闻名 |
Bourne Again Shell | /usr/bin/bash | bash是大多数Linux系统以及Mac OS X默认的shellBash 可以说是bourne shell增强版 |
C Shell | /usr/bin/csh | C Shell Bill Joy于20世纪80年代早期,在Berkeley的加利福尼亚大学开发了C shell;主要是为了让用户更容易的使用交互式功能,并把ALGOL风格的语法结构变成了C语言风格 |
Korm Shell | /usr/bin/ksh | 贝尔实验室的David Korn在上世纪80年代初开发基于Bourne shell的源代码发展而来,向后兼容的Bourne Shell,包括C shell的诸多特性 |
.... |
- Shell 脚本执行顺序依旧遵循“从上往下、从左往右”的顺序;
- Shell 脚本就是把一些命和运算符写进脚本文件,然后完成批量重复性工作而已;
- Shell 脚本支持流程控制,如
for
、while
、if
等语句控制; - Shell 脚本句末无须标点符号标记,换行即表示语句结束;
- Shell 脚本严格区分大小写,
a
和A
是完全不同的两个字符串; - Shell 脚本通常的以
/usr/bin/bash
开头,必须以此句开头,表示 shell 脚本解释器; - Shell 脚本注释用
#
开头,但第一句除外/usr/bin/bash
; - Shell 脚本通常以
.sh
为后缀命名,约定成俗; - Shell 脚本调试可以使用
bash -x xx.sh
运行脚本,系统会打印出每一条语句及执行结果;
Shell 基础语句
序 | 语样 | 描述 | 例子 | ||
---|---|---|---|---|---|
001 | echo "string" | 打印(输出/显示)内容 | 打印 Hellow Shell 到屏幕echo "Hellow Shell." | ||
002 | > | 重定向输出(不追加,会覆盖前面已有的内容) | 把 Hellow Shell 输出到 test.txt 文档echo "Hellow Shell." > test.txt | ||
003 | >> | 追加重定向输出(末行追加,不覆盖前面已有的内容) | 把 Hellow Shell 输出到 test.txt 文档echo "Hellow Linux." >> test.txt | ||
004 | < | 重定向输入 | |||
005 | `` | 命令替换,先运行``里面的命令,然后把结果赋给变量 | 把时间赋值给DATE 变量DATE=`date %T` | ||
006 | $() | 命令替换,等同于``,但推荐使用$() | 把时间赋值给DATE 变量DATE=$(date %T) | ||
007 | ${} | 变量引用,推荐 | 声明变量 T 并打印输出到屏幕T=$(ls -l)echo ${T} | ||
008 | | | 管道符,把前一个命令执行的结果作为后一个命令的输入 | 查看文件 test.txt 并统计行数cat test.txt | wc -l | ||
009 | (()) | 双括号一般用于计算val :后增val-- : 后减 val : 先增--val : 先减! : 逻辑求反~ : 位求反** : 幂运算<< : 左位移>> : 右位移& : 位布尔和| : 位布尔或&& : 逻辑和|| : 逻辑或 | 计算5 3(( 5 3 )) | ||
010 | [[]] | 支持模式匹配,支持正则表达式(不是所有的shell都支持[[]]) | ... |
Linux 退出状态码
状态码 | 描述 |
---|---|
0 | 命令成功结束 |
1 | 一般性未知错误 |
2 | 不适合的shel命令错误 |
126 | 命令不可执行 |
127 | 没有找到相关命令 |
128 | 无效的退出参数 |
128 x | 与Linux信号x相关的严重错误 |
130 | 通过Ctrl C终止 |
255 | 正常范围之外的退出状态码 |
数组相关
- 数组定义
定义数组建议“见名知意”,元素之间用空格分隔,数组元素下标从 0 开始
arry_name=(value1 value2 value3 ...) // 格式1,适用于元素较少情况
arry_name=(
value1
value2
value3
...
) // 格式2,适用于元素较多情况
- 数组元素操作
需要注意数组的作用域,博主就遇到数组作用域问题
arry_sname=(zhangsan lisi wangwu zhaoliu) // 定义数组 arry_sname
echo ${arry_sname[0]} // 打印第一个元素
echo ${arry_sname[*]} // 打印所有元素
echo ${arry_sname[@]} // 打印所有元素
echo ${#arry_sname[*]} // 打印数组长度
echo ${#arry_sname[@]} // 打印数组长度
- 素组元素修改
arry_sname[3]=value4 // 添加新的元素,如果下标元素存在,则值会被替换
unset arry_sname[3] // 删除下标为3的数组元素
unset arry_snme // 删除数组
Shell 测试语句
在Shell 脚本中,表达式要 [] 括起来,且表达式两边均要有空格
- 数值比较
比较表达式 | 描述 |
---|---|
n1 -eq n2 | n1 = n2 |
n1 -ge n2 | n1 >= n2 |
n1 -gt n2 | n1 > n2 |
n1 -le n2 | n1 <= n2 |
n1 -lt n2 | n1 < n2 |
n1 -ne n2 | n1 ≠ n2 |
- 字符串比较
比较表达式 | 描述 |
---|---|
str1 = str2 | str1 = str2 |
str1 != str2 | str1 ≠ str2 |
str1 < str2 | str1 < str2 |
str1 > str2 | str1 > str2 |
-z str1 | str1 长度非0 |
-n str1 | str1 长度为0 |
- 文件比较
比较表达式 | 描述 |
---|---|
-d file | file 是否存在且是一个目录 |
-e file | file 是否存在(目录或文件) |
-f file | file 是否存在且是一个文件 |
-r file | file 是否存在且可读 |
-s file | file 是否存在且非空 |
-w file | file 是否存在且可写 |
-x file | file 是否存在且可执行 |
-o file | file 是否存在且所有者属于当前用户 |
-G file | file 是否存在且默认组与当前用户组相同 |
file1 -nt file2 | file1 是否比 file2 新 |
file1 -ot file2 | file1 是否比 file2 旧 |
Shell 流程控制语句
- IF 语句
// 单条件
if 条件;then
命令1
命令2
....
fi
---------------------------
// 双条件
if 条件;then
命令1
命令2
....
else
命令3
命令4
....
fi
---------------------------
// 多条件
if 条件1;then
命令
elif 条件2;then
命令
elif 条件3;then
命令
else
命令
fi
- While 语句
// while 从某种意义上来讲,可以说是 if-then 语句和 for 循环的混杂体
// while 语句中,只有当测试条件为 true 时,才会不断循环下去,直至遇到 false
while 测试条件
do
命令
done
- For 语句
// for 语句是按行逐一遍历数据,以回车换行为分割
// list 支持命令,支持变量引用
// for 循环默认会以空格换行,所有如果你的行有空格的话
// 在 for 循环前,设置换行符(其它符号类似) IFS.old=$IFS;IFS=$'n'
// 同时在 for 循环完成后,记得还原 IFS=$IFS.old
for var in list
do
命令
done
// Bash for 语句支持C语言风格,注意空格
for (( i=1;i<10;i ))
do
命令
done
// for 支持多变量,注意空格
for (( i=1,j=10;i<10;i ,j-- ))
do
命令
done
- case 语句
case 变量 in
值a)
代码 A
;;
值b)
代码 B
;;
值c)
代码 C
;;
*)
代码 D
;;
esac
Shell 函数创建与调用
- 函数创建(function)
// 语法格式,其中 function可以省略,但是建议标准化格式
function name {
命令
内容
}
- 函数调用
// 调用函数,直接写函数名即可
test
sed、awk 用法
- sed 编辑器(流编辑器)
// sed 常见用法
// 常规替换字符,默认情况只替换第一次匹配到的字符串
sed 's/str_old/str_new' file
// 按要求替换(flag)
sed 's/str_old/str_new/3' file // 匹配到的第三处替换,3 是需要替换的第几次匹配到的意思
sed 's/str_old/str_new/g' file // 匹配到全文替换
sed '2s/str_old/str_new' file // 按行匹配替换:匹配第二行内容,并替换
sed '2,3s/str_old/str_new' file // 从第二行开始匹配,到第三行结束,并替换
sed '2,$s/str_old/str_new' file // 从第二行开始全文匹配,并替换
// 删除行操作
sed '5d' file // 删除文件 file 第 5 行内容
sed '2,7d' file // 删除文件 file 第 2~7 行内容
sed '7,$d' file // 删除文件 file 第 7 行以后所有的行
// 插入操作,如果使用变量,请使用双引号
sed -i "Line i str" file // 在 Line行前插入 str(新行),i 前可以加数字(3i)表示第几行前插入
sed -i 'Line a str" file // 在 Line行后插入 str(新行),a 前可以加数字(3a)表示第几行后插入
// 追加操作
Shell 小技巧/样例
- 跳出循环语句
// 跳出当前循环
break
// 跳出指定循环,n 是循环层级
break n
- 关键字匹配(涉及正则表达式)
// 匹配关键字信息,str1 字符串包含 str2 内容
[[ str1 =~ str2 ]]
- 字符串替换
// 字符串替换,如果末尾加 /g 表示全部替换
var1='abc123'
var=${var1/'bc1'/'BC1'}
- EOF 格式化输出
// 格式输出到指定文件,EOF 只是标记,不是关键字
cat >> test.txt <<EOF
内容
命令
EOF
- 提示并接收用户输入数据
// read 可以接收用户输入的内容,把用户敲入的用户赋值给 username
read -p "请输入用户名:" username
// 设置等待输入超时
read -t 5 -p "请输入用户名:" username
// 隐藏模式输入,如 Linux 输入密码一样
read -s -p "请输入密码:" userpasswd
- Shell 多进程示例
- 正则表达式
待更新...