RUN__IT # 快速掌握shell编程

shell的定义

在计算机科学中,Shell就是一个命令解释器。
shell是位于操作系统和应用程序之间,是他们二者最主要的接口,shell负责把应用程序的输入命令信息解释给操作系统,将操作系统指令处理后的结果解释给应用程序。

查看系统shell信息

查看当前系统的shell类型
echo $SHELL

查看当前系统环境支持的shell
[root@linux-node1 ~]# cat /etc/shells
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin

shell脚本定义

当可执行的Linux命令或语句不在命令行状态下执行,而是通过一个文件执行时,我们称文件为shell脚本。
创建脚本

创建脚本的常见编辑器是 vi/vim.

shell脚本的命名简单来说就是要有意义

脚本示例
#!/bin/bash
# 这是临时shell脚本
echo ‘nihao’
echo ‘itcast’

脚本执行效果
[root@linux-node1 ~]# /bin/bash itcast.sh
nihao
itcast

注释内容

除了首行的#不是注释外,其他所有行内容,只要首个字符是#,那么就表示该行是注释

#!/bin/bash
echo '1'
# echo '2'			# 这一行就表示注释
echo '3'

多行注释有两种方法::<<! ... !  和 :<<字符 ... 字符

#!/bin/bash
echo '1'
:<<! echo '2'
echo '3'
echo'4'
!
echo'5'

shell执行的方式
Shell脚本的执行通常可以采用以下几种方式

bash /path/to/script-name	或	/bin/bash /path/to/script-name	(强烈推荐使用)
/path/to/script-name		或	./script-name	(当前路径下执行脚本)
source script-name			或	. script-name	(注意“.“点号)

脚本开发规范

1.脚本命名有意义,后缀是.sh

2.脚本文件首行是脚本解释器:#!/bin/bash

3.脚本解释器后面要有脚本的基本信息,尽量用英文(脚本名称,脚本功能,脚本版本,脚本作者,联系方式等)

4.脚本文件常见执行方式:bash 脚本名

5.脚本内容执行:从上到下依次执行

6.优秀的书写习惯

7.通过缩进让代码易读(该有的空格就要有)

变量

本地变量

方式一:变量=变量值

变量值必须是一个整体,中间没有特殊字符。

方式二:变量名=‘变量值’

我看到的内容,我就输出什么内容

方式三:变量名=“$变量名 变量值”

如果变量值中有可解析的变量,先解析($变量名)然后将结果和其他内容组合到一起,赋给变量名

命令变量定义方式

方式一:

变量名=命令 注意:`是反引号

方式二:

变量名=$(命令)

全局变量

全局变量就是:在当前系统的所有环境下都能生效的变量

查看全局变量命令:

env 只显示全局变量

定义全局变量
方法一:
变量=值
export 变量

方法二:
export 变量=值

变量查看和取消

查看
方式一:
$变量名

方式二:
"$变量名"

方式三:
${变量名}

方式四:
"${变量名}"
标准写法

取消变量
unset 变量名
也可以删除本地变量

shell内置变量

脚本文件有关

$0	获取当前执行的脚本文件名,包括脚本路径
  #!/bin/bash
  # 获取脚本的名称
  echo "我脚本的名称是: file.sh"
  echo "我脚本的名称是:$0"

$# 	获取当前脚本传入参数的数量
$n 	获取当前脚本传入的第n个位置的参数
  #!/bin/bash
  # 获取当前脚本传入的参数数量
  echo "当前脚本传入的参数数量是: $#"
  # 获取指定位置的参数
  echo "第一个位置的参数是: $1"
  echo "第二个位置的参数是: $2"
  echo "第三个位置的参数是: $3"
  echo "第四个位置的参数是: $4"

$?	获取文件执行或者命令执行的返回状态值
  # bash nihao
  bash: nihao: No such file or directory
  # echo $?
  127

  # ls
  file1.sh  num.sh  test.sh  weizhi.sh
  # echo $?
  0

字符串精确截取

格式:${变量名:起始位置:截取长度}

示例:
  ${file:0:5}		从第1个字符开始,截取5个字符
  ${file::5}		从第1个字符开始,截取5个字符
  ${file:5:5}		从第6个字符开始,截取5个字符
  ${file:5}			从第6个字符开始,截取后面所有的字符
  ${file:0-5}		从倒数第5个字符开始,截取后面所有的字符
  ${file:0-6:3}		从倒数第6个字符开始,截取之后的3个字符

默认值相关

格式一:
变量a如果有内容,那么就输出a的变量值
变量a如果没有内容,那么就输出默认的内容
${变量名:-默认值}

如果我输入的参数为空,那么输出内容是 "您选择的套餐是: 套餐 1"
如果我输入的参数为n,那么输出内容是 "您选择的套餐是: 套餐 n"
#!/bin/bash
# 套餐选择演示
a="$1"
echo "您选择的套餐是: 套餐 ${a:-1}"


格式二:
无论变量a是否有内容,都输出默认值
${变量名+默认值}

不管我说国家法定结婚年龄是 多少岁,都输出 国家法定结婚年龄(男性)是 22 岁
#!/bin/bash
# 默认值演示示例
a="$1"
echo "国家法定结婚年龄(男性)是 ${a+22} 岁"

表达式

区分不同的情况以确定执行何种操作

测试语句

Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0,表示成功,值为其他时,表示失败。

格式A:test 条件表达式
格式B:[ 条件表达式 ]
后者为常用,但后者需要注意方括号[  ]与条件表达式之间至少有一个空格

条件表达式

逻辑表达式:一般用于判断多个条件之间的依赖关系

命令1  &&  命令2
如果命令1执行成功,那么我才执行命令2		-- 夫唱妇随
如果命令1执行失败,那么命令2也不执行
# [ 1 = 1 ] && echo "条件成立"
条件成立
# [ 1 = 2 ] && echo "条件成立"
#

命令1 || 命令2
如果命令1执行成功,那么命令2不执行	-- 对着干
如果命令1执行失败,那么命令2执行
# [ 1 = 2 ] || echo "条件不成立"
条件不成立
# [ 1 = 1 ] || echo "条件不成立"
#

文件表达式

-f		判断输入内容是否是一个文件
# [ -f weizhi.sh ] && echo "是一个文件"
是一个文件
# [ -f weizhi.sddh ] || echo "不是一个文件"
不是一个文件

-d		判断输入内容是否是一个目录
# [ -d weizhi.sddh ] || echo "不是一个目录"
不是一个目录
# mkdir nihao
# [ -d nihao ] && echo "是一个目录"
是一个目录

-x		判断输入内容是否可执行
# [ -x age.sh ] || echo "文件没有执行权限"
文件没有执行权限
# [ -x test.sh ] && echo "文件有执行权限"
文件有执行权限

数值操作符

n1 -eq n2            相等
n1 -gt n2            大于
n1 -ge n2            大于等于
n1 -lt n2            小于
n1 -le n2            小于等于
n1 -ne n2            不等于

字符串比较

str1 == str2	str1和str2字符串内容一致
str1 != str2	str1和str2字符串内容不一致,!表示相反的意思
root@ubuntu:~# [ a == a ]
root@ubuntu:~# echo $?
0
root@ubuntu:~# [ a != a ]
root@ubuntu:~# echo $?
1

计算表达式

计算表达式,简单来说就是对具体的内容进行算数计算

方式一:
$(())  		$(( 计算表达式 ))
格式:a=$((变量名a+1))
注意:表达式范围内,空格不限制
root@ubuntu:~# echo $((100/5))
20


方式二:
let			let 计算表达式
格式:let	变量名a=变量名a+1
注意:表达式必须是一个整体,中间不能出现空格等特殊字符
root@ubuntu:~# i=1
root@ubuntu:~# let i=i+7
root@ubuntu:~# echo $i
8

注意:
$(())中只能用+-*/和()运算符,并且只能做整数运算

linux常见符号

重定向符号

在shell脚本中有两种常见的重定向符号 > 和 >>

>符号表示将符号左侧的内容,以覆盖的方式输入到右侧文件中
查看文件内容

admin-1@ubuntu:~$ cat file.txt 
nihao
使用重定向符号给文件中增加内容
admin-1@ubuntu:~$ echo "file1.txt" > file.txt
再次查看文件内容
admin-1@ubuntu:~$ cat file.txt 
file1.txt

>> 符号 表示将符号左侧的内容,以追加的方式输入到右侧文件的末尾行中
查看文件内容
admin-1@ubuntu:~$ cat file.txt 
file1.txt
使用重定向符号给文件中增加内容
admin-1@ubuntu:~$ echo "file2.txt" >> file.txt 
再次查看文件内容
admin-1@ubuntu:~$ cat file.txt 
file1.txt
file2.txt

管道符 |

命令1 | 命令2
管道符左侧命令1 执行后的结果,传递给管道符右侧的命令2使用
查看当前系统中的全局变量SHELL

admin-1@ubuntu:~$ env | grep SHELL
SHELL=/bin/bash

后台展示符号 &

& 就是将一个命令从前台转到后台执行
格式:命令 &

admin-1@ubuntu:~# sleep 4
界面卡住4秒后消失
admin-1@ubuntu:~# sleep 10 &
[1] 4198
admin-1@ubuntu:~# ps aux | grep sleep
root     4198  0.0  0.0   9032   808 pts/17   S    21:58   0:00 sleep 10
root     4200  0.0  0.0  15964   944 pts/17   S+   21:58   0:00 grep --color=auto sleep

Ctrl+Z 让当前任务转入到后台并停止
jobs 查看后台任务
fg 让后台进程转入到前台执行
bg 让后台停止的任务继续在后台执行

全部信息符号 2>&1

1 表示正确输出的信息
2 表示错误输出的信息
2>&1 代表所有输出的信息

标准正确输出示例
cat nihao.txt 1>> zhengque 
标准错误输出示例
dsfadsfadsfa 2>> errfile

linux系统垃圾桶

/dev/null 是linux下的一个设备文件,

这个文件类似于一个垃圾桶,特点是:容量无限大

常见命令

grep命令

grep命令是我们常用的一个强大的文本搜索命令
格式:grep [参数] [关键字] <文件名>
-c:只输出匹配行的计数
-n:显示匹配行及行号
-v:显示不包含匹配文本的所有行
-i:不区分大小写

sed命令

sed行文件编辑工具。以行为单位
命令格式:sed [参数] '<匹配条件> [动作]' [文件名]

参数
参数为空:表示sed的操作效果,实际上不对文件进行编辑
-i:表示对文件进行编辑

匹配条件
关键字匹配格式:'/关键字/'
注意:隔离符号/可以更换成@、#、!等符号

数字行号匹配

动作
-a:在匹配到的内容下一行增加内容
-i:在匹配到的内容上一行增加内容
-d:删除匹配的内容
-s:替换匹配到的内容
上面的动作应该在参数为-i的时候使用,不然无效果

替换命令

命令格式:sed -i [替换格式] [文件名]
替换命令的写法: 's#原内容#替换后内容#'

原内容
admin-1@ubuntu:~$ cat sed.txt 
nihao sed sed sed
nihao sed sed sed
nihao sed sed sed

替换每行 首个匹配内容:
替换首每行的第1个sed为SED
admin-1@ubuntu:~$ sed -i 's#sed#SED#' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
nihao SED sed sed
nihao SED sed sed
nihao SED sed sed

替换全部匹配内容:
替换全部sed为SED
admin-1@ubuntu:~$ sed -i 's#sed#SED#g' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
nihao SED SED SED
nihao SED SED SED
nihao SED SED SED

指定行号替换首个匹配内容:
替换第2行的首个SED为sed
admin-1@ubuntu:~$ sed -i '2s#SED#sed#' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
nihao SED SED SED
nihao sed SED SED
nihao SED SED SED

首行指定列号替换匹配内容:
替换每行的第2个SED为sed
admin-1@ubuntu:~$ sed -i 's#SED#sed#2' sed.txt
admin-1@ubuntu:~$ cat sed.txt 
nihao SED sed SED
nihao sed SED sed
nihao SED sed SED

指定行号列号匹配内容:
sed -i '行号s#原内容#替换后内容#列号' 文件名
替换第3行的第2个SED为sed
admin-1@ubuntu:~$ sed -i '3s#SED#sed#2' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
nihao SED sed SED
nihao sed SED sed
nihao SED sed sed

增加操作

在指定行号的 下一行 增加内容
格式:sed -i '行号a\增加的内容' 文件名
admin-1@ubuntu:~$ sed -i '2a\zengjia-2' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
nihao SED sed SED
nihao sed SED sed
zengjia-2
nihao SED sed sed
如果增加多行,可以在行号位置写个范围值,彼此间使用逗号隔开,例如
sed -i '1,3a\增加内容' 文件名
admin-1@ubuntu:~$ sed -i '1,3a\tongshi-2' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
nihao SED sed SED
tongshi-2
nihao sed SED sed
tongshi-2
zengjia-2
tongshi-2
nihao SED sed sed

在指定行号的 当行 增加内容
格式:sed -i '行号i\增加的内容' 文件名
admin-1@ubuntu:~$ sed -i '1i\insert-1' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
insert-1
nihao SED sed SED
tongshi-2
nihao sed SED sed
tongshi-2
zengjia-2
tongshi-2
nihao SED sed sed

删除操作

指定行号删除
格式:sed -i '行号d' 文件名
删除第4行内容
admin-1@ubuntu:~$ sed -i '4d' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
insert-1
nihao SED sed SED
tongshi-2
tongshi-2
zengjia-2
tongshi-2
nihao SED sed sed
如果删除多行,可以在行号位置多写几个行号,彼此间使用逗号隔开,例如
sed -i '1,3d' 文件名
admin-1@ubuntu:~$ sed -i '3,5d' sed.txt 
admin-1@ubuntu:~$ cat sed.txt 
insert-1
nihao SED sed SED
tongshi-2
nihao SED sed sed

awk

awk是一个功能非常强大的文档编辑工具,它不仅能一行为单位还能以列为单位处理文件。
命令格式:awk [参数] ' [动作] ' [文件名]
常见参数:-F	指定行的分隔符
常见动作:
		print 	显示内容
		$0		显示当前行所有内容
		$n		显示当前行的第n列内容,如果存在多个$n,他们之间使用逗号隔开
常见内置变量
		FILENAME 	当前输入文件的文件名,该变量是只读的
		NR 			指定显示行的行号
		NF 			输出 最后一列的内容
		OFS 		输出格式的列分隔符,缺省是空格
		FS 			输入文件的列分融符,缺省是连续的空格和Tab

模板文件内容
admin-1@ubuntu:~$ cat awk.txt 
nihao awk awk awk
nihao awk awk awk

打印指定列内容
打印第1列的内容
admin-1@ubuntu:~$ awk '{print $1}' awk.txt 
nihao
nihao

指定行打印内容
打印第一行第1和第3列内容
admin-1@ubuntu:~$ awk  'NR==1 {print $1,$3}' awk.txt 
nihao awk

指定隔离分隔符,查看内容
admin-1@ubuntu:~$ cat linshi.txt 
root:x:0:0:root:/root:/bin/bash
admin-1@ubuntu:~$ awk -F ':' '{print $1,$7}' linshi.txt 
root /bin/bash

设置显示分隔符,显示内容
admin-1@ubuntu:~$ awk 'BEGIN{OFS=":"} {print NR,$0}' awk.txt 
1:nihao awk awk awk
2:nihao awk awk awk

find命令

命令格式:
		find [路径] [参数] [关键字]
参数详解
-name 按照文件名查找文件。
-perm 按照文件权限来查找文件。
-user 按照文件属主来查找文件。
-group 按照文件所属的组来查找文件。
-type 查找某一类型的文件,诸如:
	b - 块设备文件		d - 目录			c - 字符设备文件
	p - 管道文件		l - 符号链接文件	f - 普通文件。
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-mindepth n:在查找文件时,查找当前目录中的第n层目录的文件,然后再在其子目录中查找。
! :	表示取反

在当前系统中查找一个叫awk的文件
admin-1@ubuntu:~$ sudo find /home/admin-1/ -name "awk.txt"
/home/admin-1/awk.txt
在当前系统中查找文件类型为普通文件的文件
admin-1@ubuntu:~$ find /tmp -type f
/tmp/.X0-lock
/tmp/vgauthsvclog.txt.0
/tmp/unity_support_test.0
/tmp/config-err-4igbXW

流程控制

单分支if语句

语法格式
if [ 条件 ]
then
  	指令
fi

单一条件,只有一个输出
#!/bin/bash
# 单if语句的使用场景
if [ "$1" == "nan" ]
then
   echo "您的性别是 男"
fi

双分支if语句

语法格式
if [ 条件 ]
then
  	指令1
else
 	指令2
fi

一个条件,两种结果
#!/bin/bash
# 单if语句的使用场景
if [ "$1" == "nan" ]
then
   echo "您的性别是 男"
else
   echo "您的性别是 女"
fi	

多分支if语句

语法格式
if [ 条件 ]
then
  	指令1
elif [ 条件2 ]
then
 	指令2
else
 	指令3
fi

n个条件,n+1个结果
#!/bin/bash
# 单if语句的使用场景
if [ "$1" == "nan" ]
then
   echo "您的性别是 男"
elif [ "$1" == "nv" ]
then
   echo "您的性别是 女"
else
   echo "您的性别,我不知道"
fi



多if语句生产场景:	服务的启动
需求:要求脚本执行需要有参数,通过传入参数来实现不同的功能。

参数和功能详情如下:
参数 			执行效果
		start			服务启动中...
		stop			服务关闭中...
		restart			服务重启中...
		*				脚本 X.sh 使用方式 X.sh [ start|stop|restart ]

脚本内容
admin-1@ubuntu:/data/scripts/python-n# cat if.sh 
#!/bin/bash
# 多if语句的使用场景
if [ "$1" == "start" ]
then
   echo "服务启动中..."
elif [ "$1" == "stop" ]
then
   echo "服务关闭中..."
elif [ "$1" == "restart" ]
then
   echo "服务重启中..."
else
   echo "$0 脚本的使用方式: $0 [ start | stop | restart ]"
fi

case选择语句

case 语句格式
case 变量名 in
   值1)
      指令1
         ;;
   值2)
      指令2
         ;;
   值3)
 	  指令3
         ;;
esac

注意:
首行关键字是case,末行关键字esac
选择项后面都有 )
每个选择的执行语句结尾都有两个分号;

case语句示例
场景:在多if语句的基础上对脚本进行升级
需求:要求脚本执行需要有参数,通过传入参数来实现不同的功能。

参数和功能详情如下:
参数 				执行效果
start			服务启动中...
stop			服务关闭中...
restart			服务重启中...
*				脚本 X.sh 使用方式 X.sh [ start|stop|restart ]

脚本内容:
# cat case.sh 
#!/bin/bash
# case语句使用场景
case "$1" in					
	"start")					
		echo "服务启动中..."					
		;;					
	"stop")					
		echo "服务关闭中..."					
		;;							
	"restart")					
		echo "服务重启中..."					
		;;					
	*)					
		echo "$0 脚本的使用方式: $0 [ start | stop | restart ]"		
		;;					
esac

for循环语句

语法格式
for 值 in 列表
do
	语句执行
done

示例:遍历文件
#!/bin/bash
# for语句的使用
for i in $(ls /root)
do
	echo "${i}"
done

while循环语句

语法格式
while 条件
do
	执行语句
done

条件类型:命令、[[字符串表达式]]、((数字表达式))

示例
#!/bin/bash
# while的示例
a=1
while [ "${a}" -lt 5 ]
do
	echo "${a}"
	a=$((a+1))
done

until循环语句

语法格式
until 条件
do
	执行语句
done

条件类型:命令、[[字符串表达式]]、((数字表达式))

示例
#!/bin/bash
# until的示例
a=1
until ["${s}" -eq 5]
do
	echo "${a}"
done

函数

定义函数格式:
函数名(){
	函数体
}

调用函数:
函数名

传参函数格式:
传参数
函数名 参数

函数体调用参数:
函数名(){
	函数体 $n
}

示例
#!/bin/bash
# 函数的使用场景二
dayin(){
  echo "wo de mingzi shi $1"
  echo "wo de mingzi shi $2"
  echo "wo de mingzi shi $3"
}
dayin 111 df dfs

猜你喜欢

转载自blog.csdn.net/RUN__IT/article/details/89415533