Shell 脚本的编写总结
Posted 码农飞哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell 脚本的编写总结相关的知识,希望对你有一定的参考价值。
您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦。
💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通
❤️ 2. Python爬虫专栏,系统性的学习爬虫的知识点。9.9元买不了吃亏,买不了上当 。python爬虫入门进阶
❤️ 3. Ceph实战,从原理到实战应有尽有。 Ceph实战
❤️ 4. Java高并发编程入门,打卡学习Java高并发。 Java高并发编程入门
😁 5. 社区逛一逛,周周有福利,周周有惊喜。码农飞哥社区,飞跃计划
全网同名【码农飞哥】欢迎关注,个人VX: wei158556
文章目录
1. 简介
这篇文章主要是为了记录一下Shell脚本的使用语法,前几天写了一个shell脚本,其中,也遇到了一些语法不清楚的情况,在此记录一下已备后续使用。
2. 什么是Shell脚本
Shell脚本(英语:Shell script)是一种电脑程序与文本文件,内容由一连串的shell命令组成,经由Unix Shell直译其内容后运作。被当成是一种脚本语言来设计,其运作方式与直译语言相当,由Uninx shell扮演命令行解释器的角色,在读取shell script之后,依次运行其中的shell命令,之后输出结果。利用Shell script可以进行系统管理、文件操作等。
2.1. 来个实例
创建一个名为demo1.sh的shell脚本文件,在该shell脚本中添加如下内容:
#!/bin/sh
cd ~
mkdir shell_tut
cd shell_tut
for((i=0;i<3;i++));do
touch test_$i.txt
done
点击保存之后,在通过命令sh demo1.sh
来执行该脚本。即可达到我们预期的效果。
实例解析:
- 第1行:指定脚本解析器,这里是用
/bin/sh
做解析器的。 - 第2行:切换到当前用户的
home
目录,因为我是用root用户登录的,所以我这边的用户目录是/root
- 第3行:创建一个目录shell_tut
- 第4行:切换到shell_tut目录
- 第5行:循环条件,一共循环10次
- 第6行:创建一个
test_1....2.txt
文件 - 第7行:循环体结束
cd, mkdir, touch都是系统自带的程序,一般在/bin或者/usr/bin目录下。for, do, done是sh脚本语言的关键字。
3. 环境
shell编程跟java、php编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。当前主流的操作系统都支持shell编程,本文所述的shell编程是指Linux下的shell,讲的基本都是POSIX标准下的功能,所以,也适用于Unix及BSD(如Mac OS)。
系统 | 说明 |
---|---|
Linux | Linux默认安装就带了shell解释器。 |
Mac OS | Mac OS 不仅带了sh、bash这两个最基础的解释器,还内置了ksh、csh、zsh等不常用的解释器 |
Windows | windows出厂时没有内置shell解释器,需要自行安装,为了同时能用grep, awk, curl等工具,最好装一个cygwin或者mingw来模拟linux环境。 |
4.脚本解释器
4.1. sh
即Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh
,由Bell Labs开发。
4.2. bash
Bash是Bourne shell,属GNU Project,二进制文件路径通常是/bin/bash。业界通常混用bash、sh、和shell
5. 第一个shell脚本
5.1. 编写
打开文件编辑器,新建一个文件,扩展名为sh(sh代表shell),在脚本前面一般会加上#!/bin/bash
或者#!/bin/sh
用于指定解释器。
输入一些代码,第一行一般是这样的:
#!/bin/sh
#!/bin/bash
#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行。
需要注意的是编码格式是需要是Unix(LF) 下的UTF-8格式。
5.2. 运行
运行Shell脚本有两种方法:
- 第一种方法,
sh 【shell脚本名称】
sh demo1.sh
- 第二种方法
./【shell脚本名称】
chmod +x demo1.sh
./demo1.sh
需要注意的是,一定要写成./demo1.sh
,而不是demo1.sh
,运行其他二进制的程序也一样,直接写demo1.sh
,Linux系统会去PATH里寻找有没有叫demo1.sh的,而只有/bin,/sbin,/usr/bin,/usr/sbin等在PATH里。你的当前目录通常不在PATH里,所以写成demo1.sh是会找不到命令的,要用./demo1.sh告诉系统说,就在当前目录找。
6. shell变量
6.1.定义变量
定义变量时,变量名不加美元符合,如:
project_path=/data/server/demo_project
注意,变量名和等号之间不能有空格,变量的命令需要遵循如下原则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线_。
- 不能使用标点符号。
- 不能使用bash里的关键字
6.2. 使用变量
使用定义的变量,只需要在变量名前面加美元符号即可,如:
project_path=/data/server/demo_project
echo $project_path
echo $project_path
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
7. Shell 字符串
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。
7.1. 单引号
str='这是一个单纯的字符串'
echo $str
7.2. 双引号
name="码农飞哥"
echo "我的名字是$name"
双引号与单引号的区别在于,双引号里面可以有变量,而单引号里面添加变量无效,它只会原样输出单引号里的内容。
7.3. 获取字符串长度
string="abcd"
echo $#string # 输出 4
提取子字符串
以下实例从字符串第 2 个字符开始截取 4 个字符:
7.4. 定义数组
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:数组名=(值1 值2 ... 值n)
例如:
array_name=(
"张三",
"李四",
"王五",
)
echo $array_name[1]
8. 运算符
8.1. 算术运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk和expr,expr最常用,expr是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个树相加(注意使用的是反引号**`,而不是单引号’**)
例如:
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
执行脚本,输出结果是:两数之和为 : 4
PS:需要注意的是:
- 表达式和运算符之间要用空格,例如2+2是不对的,必须写成 2 + 2,
下表列出常用的算术运算符,假定变量a为10,变量b为10;
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | val=expr $a + $b 结果为30 |
- | 减法 | val=expr $a - $b 结果为0 |
* | 乘法 | expr $a \\* $b 结果为 100 |
/ | 除法 | expr $b / $a 结果为 1 |
% | 取余 | expr $b % $a 结果为 0 |
= | 赋值 | a=$b 把变量 b 的值赋给 a |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 true |
!= | 不相等。用于比较两个数字,不相同则返回 true | [ $a != $b ] 返回 false |
注意:条件表达式要放在方括号之间,并且要有空格,例如: [
a
=
=
a==
a==b] 是错误的,必须写成 [ $a == $b ]。
实例:
#!/bin/bash
#author:码农飞哥
#url:https://feige.blog.csdn.net/
a=10
b=10
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \\* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
8.2 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字,下表 列出了常用的关系运算符,假定变量a为10,变量b为10
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回true | [ $a -eq $b ] 返回 true |
-ne | 检测两个数是否不相等,不相等返回 true。 | $a -eq $b ] 返回 false |
-gt | 检测左边的数是否大于右边的,如果是,则返回true | [ $a -gt $b ] 返回 false |
-lt | 检测左边的数是否小于右边,如果是,则返回true | [ $a -gt $b ] 返回 false |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 true |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true |
实例: |
#!/bin/bash
#author:码农飞哥
#url:https://feige.blog.csdn.net/
a=10
b=10
if [ $a -eq $b ]
then
echo "$a -eq $b":"a 等于 b"
else
echo "$a -eq $b":"a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于b"
else
echo "$a -ne $b a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
8.3 逻辑运算符
假设变量a为10,变量b为15;
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
实例:
a=10
b=15
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
8.4 字符串运算符
下表列出了常用的字符串运算符,假定变量a为"abc",变量b为"efg":
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回true | [ $a = $b ] 返回 false |
!= | 检测两个字符串是否不相等,不相等返回 true | [ $a != $b ] 返回 true |
-z | 检测字符串长度是否为0,为0返回 true | [ -z $a ] 返回 false |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n “$a” ] 返回 true。 |
$ | 检测字符串是否不为空,不为空返回 true。 | [ $a ] 返回 true。 |
实例: |
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
8.5 文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。这里指定file为 /data/server/xiang/script/testscript/demo.sh
操作符 | 说明 | 举例 |
---|---|---|
-d file | 检测文件是否是目录,如果是,则返回true | [ -d $file ] 返回false |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回true | [ -f $file ] 返 true |
-r file | 检测文件是否可读,如果是,则返回true。 | [ -r $file ] 返回 true |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true |
实例: |
#!/bin/bash
file="/data/server/xiang/script/testscript/demo.sh"
ile="/var/www/runoob/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
9. shell echo命令
9.1. 显示普通字符
echo "这是一个普通字符"
9.2. 显示转义字符
echo "\\"这是一个转义字符 \\""
9.3. 显示变量
name="张三三"
echo "我的名字是$name"
9.4. 显示结果定向至文件
echo "我是一个测试文本">myfile
10. Shell流程控制
10.1 if fi
if 语句语法格式:
if condition
then
command1
....
commandN
fi
写成一行
if [ $(ps -ef|grep -c "nginx") -gt 1 ];then echo "true";fi
10.2 if else fi
if else fi 语法格式:
if condition
then
command1
command2
...
commandN
else
command
fi
实例:
a=10
b=10
if [ $a -eq $b ]
then
echo "$a -eq $b":"a 等于 b"
else
echo "$a -eq $b":"a 不等于 b"
fi
10.3 if elif fi
if elif fi的语法结构是:
a=10
b=20
if [ $a -gt $b ]
then
echo "a大于b"
elif [ $a -eq $b ]
then
echo "a等于b"
elif [ $a -lt $b ]
then
echo "a小于b"
else
echo "没有符合的条件"
fi
11. for 循环
Shell支持for循环
for循环一般格式为:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
写成一行
for var in item1 item2 ... itemN; do command1;command2...done;
当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。
in列表示可选的,如果不用它,for循环使用命令行的位置参数。
for str in 我是 码农飞哥, 做一个 堂堂正正的中国人
do
echo $str
done
通过空格区分每一个item。
12. while循环
while循环用于不断执行一系列命令,也用于从输入文件中读取数据。其语法格式为;
while condition
do
command
done
如果a小于等于6,a从1开始,每次循环都对a加1,运行上述脚本,返回数字1到6,然后终止。
a=1
while (( $a<=6 ))
do
echo $a
let "a++"
done
这里的判断条件需要用(())
,运行脚本,输出:
break 命令
break 命令允许跳出所有循环(终止执行后面的所有循环)。
13. 获取服务器IP地址
如果通过shell命令获取服务器的IP地址呢?
我们都知道通过 ifconfig
来获取服务器的网络配置情况,但是当有多个网卡的情况下,如果获取某个网卡的IP地址呢?如下图所示:如何获取网卡eth0
的IP地址呢?
命令有点点小复杂,如下所示:
current_ip=$(ifconfig eth0|grep inet|grep -v inet6|awk 'print $2')
命令解释:
ifconfig eth0
用于查询eth0网卡grep inet
用于模糊查询inet开头的网络地址grep -v inet6
用于剔除掉inet6awk 'print $2'
用于打印第二个参数。
14. 交互式的命令
shell同样支持交互式命令,shell脚本可以接收我们控制台输入的文本。
echo -n "input 文件名 :"
read
echo "输入的文件名是:$REPLY"
15. 查看文件中是否存在某内容
查找文件中是否存在某内容,可以通过cat 命令进行查找,其中/dev/null 通常被用于丢弃不需要的输出流,或作为用于输入流的空文件,这些操作通常由重定向完成,任何你想丢弃的数据都可以写入其中
丢弃标准输出
在写shell脚本的时候,只想通过命令的结果执行后面的逻辑,而不想命令执行过程中有一大堆中间结果输出,这时候可以把命令执行过程中的输入全部写入 /dev/null
if cat name.txt|grep 李三三 >/dev/null
then
echo "文本已经存在不再添加"
else
echo "文本不存在进行添加"
sed -i '$a\\李三三' name.txt
fi
总结
本文详细介绍了Shell脚本的一些基础命令,下文将主要介绍sed命令
以上是关于Shell 脚本的编写总结的主要内容,如果未能解决你的问题,请参考以下文章