锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Shell脚本编程-总

时间:2022-08-23 20:00:01 系列17p连接器

Shell脚本编程

  • 一. SHELL入门
    • 1.1 变量
        • 1.1.1 变量名规范
        • 1.1.2 位置变量
        • 1.1.3 环境变量
    • 1.2 管道
    • 1.3 退出状态码
        • 1.3.1 退出状态码描述
        • 1.3.2 更改退出状态码exit命令
  • 二. 判断与控制
    • 2.1 if-then 语句
    • 2.2 if-then-else 语句
    • 2.3 嵌套if语句
    • 2.4 条件测试-数值比较
    • 2.5 条件测试-字符串比较
    • 2.6 条件测试-文件比较
    • 2.7 符合条件的测试
    • 2.8 if-then中使用双括号
    • 2.9 if-then使用双方括号
    • 2.10 case命令
  • 三. 循环与控制
    • 3.1 for循环
    • 3.2 while循环
    • 3.3 until命令
    • 3.4 break命令
    • 3.5 continue命令
    • 3.6 处理循环输出
  • 四. 高级变量用法
    • 4.1 变量替换和测试
    • 4.2 字符串处理
    • 4.3 命令替换
    • 4.4 有类型变量
    • 4.5 bash数学运算
        • 4.5.1 bash数学运算之expr
        • 4.5.2 bash数学运算之bc
  • 五. 函数的高级用法
    • 5.1 定义和使用函数
    • 5.2 将参数传递给函数
    • 5.3 函数返回值
    • 5.4 局部变量和全局变量
    • 5.5 函数库
  • 六. 文件查找
    • 6.1 find命令
    • 6.2 find、locate、whereis和which总结和应用场景分析
  • 七. 三剑客之一的文件处理grep
    • 7.1 grep命令
        • 7.1.1 语法格式
        • 7.1.2 grep参数
        • 7.1.3 grep和egrep
    • 7.2 三剑客之一的文件处理sed
        • 7.2.1 sed工作模式
        • 7.2.2 sed选项
        • 7.2.3 sed中的pattern详解
        • 7.2.4 sed详细说明编辑命令
        • 7.2.5 反向引用
        • 7.2.6 利用sed查找文件内容
        • 7.2.7 利用sed删除文件内容
        • 7.2.8 利用sed修改文件内容
        • 7.2.9 利用sed添加文件内容
    • 7.3 三剑客之一的文本处理awk
        • 7.3.1 awk工作模式
        • 7.3.2 awk内置变量
        • 7.3.3 awk格式输出printf
        • 7.3.4 awk模式匹配的两种用法
        • 7.3.5 awk表达式用法
        • 7.3.6 awk动作中的条件和循环句子
        • 7.3.7 awk中间的字符串函数
        • 7.3.8 awk的常用选项
        • 7.3.9 awk使用中数组
        • 7.3.10 实例
  • 八. Shell实战脚本操作数据库
    • 8.1 导入测试数据
        • 8.1.1 载入数据
        • 8.1.2 赋予用户数据库权限
    • 8.2 Shell脚本与MySQL数据库交互
        • 8.2.1 mysql详细说明命令参数:
        • 8.2.2 实例
    • 8.3 利用Shell脚本导入文本数据MySQL中
    • 8.4 备份MySQL并通过数据FTP将其传输到远端主机
        • 8.4.1 mysqldump常用参数详解:
        • 8.4.2 FTP常用指令
        • 8.4.3 需求
  • 九. 大型脚本工具开发实战
    • 9.1 需求描述:
    • 9.2 功能函数代码
    • 9.3 程序主流程设计和代码实现

一. SHELL入门

1.1 变量

1.1.1 变量名规范

  • 变量是由任何字母、数字和下划线组成的字符串,不能从数字开始。
  • 区分字母大小写
  • 变量、等号、值中间不能出现任何空格

实例
在这里插入图片描述

注:$ var1 $ var2不能实现相加,$ var1,$ var默认情况下,2作为字符串处理

1.1.2 位置变量

在执行命令或脚本时,我们可以使用位置参数变量来表示这些参数。

命令行所有参数,把所有的参数看成一个整体
位置参数变量 描述
$n n 为数字,$ 0 代表Shell本身的文件名,$ 1?$ 9 代表第 1 ~ 9 个参数,10 大括号应包含上述参数, 如 $ {10}
$*
$@ 命令行中所有参数,但每个参数区别对待
$# 命令行中所有参数的个数

实例

$ @和$ *都表示命令行所有参数,但是$ *将命令行的所有参数看成一个整体,而$ @则区分各个参数

1.1.3 环境变量

环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或多个应用程序将使用到的信息。Linux是一个多用户的操作系统,每个用户登录系统时都会有一个专用的运行环境,通常情况下每个用户的默认的环境都是相同的。这个默认环境就是一组环境变量的定义。每个用户都可以通过修改环境变量的方式对自己的运行环境进行配置。

分类

  • 对所有用户生效的环境变量 /etc/profile

  • 对特定用户生效的环境变量 ~ /.bashrc或者~/.bash_profile

  • 临时有效的环境变量 export

常用环境变量

环境变量 含义
PATH 命令搜索的路径
HOME 用户家目录的路径
LOGNAME 用户登录名
PWD 当前所在路径
HISTFILE 历史命令的保存文件
HISTSIZE 历史命令保存的最大行数
HOSTNAME 主机名
SHELL 用户当前使用的SHELL
PS1 一级命令提示符
TMOUT 用户和系统交互过程的超时值
IFS 系统输入分隔符
OFS 系统输出分隔符

实例

1.2 管道

将一个命令的输出作为另一个命令的输入

实例

  • 列出所有安装过的软件包
rpm -qa

rpm命令是RPM软件包的管理工具
  • 列出与python相关的软件包
rpm -qa | grep python


Linux grep 命令用于查找文件里符合条件的字符串。
    -a :将 binary 文件以 text 文件的方式搜寻数据
    -c :打印匹配次数
    -f  两个文件相同行  如,grep -f file1 file2
    -h 不显示匹配行所在文件名
    -i :忽略大小写的不同,所以大小写视为相同
    -l 只显示匹配到的文件名
    -n :顺便输出行号
    -o 只显示匹配的字符
    -v :只显示不匹配的行。 
    --color=auto :可以将找到的关键词部分加上颜色的显示喔!
  • 显示与python相关的软件包的行数
rpm -qa | grep python | wc -l


Linux wc命令用于计算字数
    -c或--bytes或--chars 只显示Bytes数。
    -l或--lines 只显示行数。
    -w或--words 只显示字数。
    --help 在线帮助。
    --version 显示版本信息。

1.3 退出状态码

1.3.1 退出状态码描述

所有的shell命令都使用退出状态吗来告知shell它已执行完毕

退出状态码是一个0~255的整数值

Linux提供了一个$?来捕获退出状态码的值,所以,可以通过echo语句测试命令是否运行成功。

一般来讲,退出状态 0 表示正常执行,没有遭遇任何问题。其他非零的状态码均表示失败。

状态码 描述
0 命令成功结束
1 一般性未知错误
2 不适合的shell 命令
126 找到了该命令但无法执行
127 没找到命令
128 无效的退出参数
128+x 与linux信号x相关的严重错误
130 通过ctrl+C终止的命令
255 正常范围之外的退出状态码

实例

1.3.2 改变退出状态码的exit命令

退出状态码是以上一条指令的返回结果为准
使用exit命令改变退出状态码

exit $exit_code

exit 48 或者 exit 125 或者exit 0

二. 判断与控制

2.1 if-then 语句

语法:

if command | condition     
then 
    commands
fi

实例

#!/bin/bash

if pwd
then 
	echo "It works"
fi

2.2 if-then-else 语句

语法:

if command | condition     
then 
    commands
else
    commands
fi

实例

#!/bin/bash

if pwd
then 
	echo "It works"
fi

2.3 嵌套if语句

语法:

if command | condition     
then 
    commands
elif command | condition 
then
    commands
else
    commands
fi

2.4 条件测试-数值比较

语法:

if condition     
then 
    commands
fi

或者

if condition;then 
    commands
fi

数值比较

数值比较 含义
n1 -eq n2 n1和n2相等,则返回true;否则返回false
n1 -ne n2 n1和n2不相等,则返回true;否则返回false
n1 -gt n2 n1大于n2,则返回true;否则返回false
n1 -ge n2 n1大于等于n2,则返回true;否则返回false
n1 -lt n2 n1小于n2,则返回true;否则返回false
n1 -le n2 n1小于等于n2,则返回true;否则返回false

实例

#!/bin/bash

if [ $1 -eq $2 ];then 
	echo "$1 = $2"
elif [ $1 -gt $2 ];then 
	echo "$1 > $2"
elif [ $1 -lt $2 ];then 
	echo "$1 < $2"
fi
        

2.5 条件测试-字符串比较

字符串比较

字符串比较 含义
str1 = str2 相等比较
str1 != str2 不相等比较
str1 < str2 str1小于str2为true
str1 > str2 str1大于str2为true
-n str1 str1长度不是0则为true
-z str1 str1长度是0则为true

实例

#!/bin/bash
var1='hello'
var2='world'
if [ $var1 = $var2 ];then 
	echo "equal"
else
	echo "not equal"
fi

#!/bin/bash
var1='hello'
var2='world'
if [ $var1 < $var2 ];then 
	echo "<"
else
	echo ">"
fi

<被当作了重定向,需要进行转义

#!/bin/bash
var1='hello'var2='world'
if [ $var1 \< $var2 ];then 
	echo "<"
else
	echo ">"
fi

#!/bin/bash
var1=''
var2='world'
if [ -n "$var1" ];then 
	echo "var1 is not null"
else
	echo "var1 is null"
fi

2.6 条件测试-文件比较

文件比较

文件比较 含义
-d file file是否为目录
-f file file是否为文件
-e file file是否存在
-r file file是否可读
-w file file是否可写
-x file file是否可执行
-s file file存在且非空
file1 -nt file2 file1比file2新为true
file1 -ot file2 file1比file2旧为true

实例

#!/bin/bash

if [ -d /usr/local ];then 
	echo "yes"
else
	echo "no"
fi

#!/bin/bash

if [ /usr/local/test1  -nt /usr/local/test2 ];then 
	echo "new"
else
	echo "old"
fi

2.7 符合条件测试

语法:

语法1 “与”
if condition1 && condition2  
then 
    commands
fi

语法2 “或”

if condition1 || condition2  
then 
    commands
fi

实例

#!/bin/bash

var1=56
var2=34
var3=89
if [ $var1 -gt $var2 ] && [ $var2 -lt $var3 ];then 
	echo " $var1 > $var2 并且 $var2 < $var3"
fi

2.8 if-then中使用双括号

使用双括号进行算术运算

语法:

if ((expression))
then 
    commands
fi

注:

  • 双括号结构中,变量名引用可以加$,也可以不加

  • 运算符前后可以有空格,也可以没有

  • 可以用于if,for,while等循环控制结构中

  • 多个运算符使用逗号分隔

可用运算符

运算符 含义
value++ 后增
value– 后减
++value 先增
–value 先减
! 逻辑求反
== 相等
> 大于
< 小于
>= 大于等于
<= 小于等于
&& 逻辑与

实例

#!/bin/bash
a=10
((a+=10))
echo $a

2.9 if-then中使用双方括号

单方括号语法

if [ $n1 -gt $n2 ] && [ $n2 -lt $n3 ]   
then 
    commands
fi

改为双方括号语法

if [ [$n1 -gt $n2  &&  $n2 -lt $n3 ]]   
then 
    commands
fi
注:
    双括号结构中,变量名引用必须加$
    [[后面必须要空格,]]前面必须有空格

2.10 case命令

语法:

case $var in
	pattern1)
		commands
		;;
	pattern2)
		commands;
		;;
esac

实例:

#!/bin/bash
case $1 in
	jack)
		echo "hello,jack"
		;;
	mike)
		echo "hello,mike"
		;;
	*)
		echo "hello everyone"
		;;
esac

三. 循环与控制

3.1 for循环

循环遍历一系列特定值,然后在结构体中针对每个特定值做处理

语法:

for var in list
do 
	commands
done

实例:

for循环读取列表值:

#!/bin/bash
for i in Beijing Shanghai Nanjing Guangzhou Zhengzhou
do 
	echo "Province is $i"
done

for i in { 
        1..20}
do 
	echo "Number is $i"
done

for循环读取变量值:

#!/bin/bash
list="Zhangsan Lisi Mike Tom"
for i in $list
do 
	echo "Name is $i"
done          

#!/bin/bash

IFS=$":" #分隔符,默认为空格或tab

list="Zhangsan:Lisi:Mike:Tom"
for i in $list
do 
	echo "Name is $i"
done

for循环从命令执行结果读取值

#!/bin/bash

FILE=$(ls /opt/)

for i in $FILE
do 
	echo "file is $i"
done

#!/bin/bash

for i in $(ls /opt/)
do 
	if [ -d /opt/$i ]
	then
		echo "$i is DIR"
	elif [ -f /opt/$i ]
	then
		echo "$i is FILE"
	fi
done

C语言风格的for循环

#!/bin/bash

for ((i=10;i<20;i++))
do 
	echo "Next Number is $i"
done

#!/bin/bash
sum=0
for (( i=1;i<101;i++))
do 
	(( sum+=$i ))	
done
echo "sum is $sum"

3.2 while循环

语法:

while command
do 
	commands
done

实例:

#!/bin/bash
num=10
while [ $num -lt 20 ]
do 
	echo "number is $num"
	((num++))
done

3.3 until命令

语法:

until command
do 
	commands
done

实例:

#!/bin/bash
num=10
until [ $num -eq 0 ]
do 
	echo "number is $num"
	((num--))
done

3.4 break命令

实例:

#!/bin/bash
num=10
for ((i=1;i<=10;i++))
do
	if ((i==5))
	then
		break
	 else
		echo "number is $i"
	fi
done

当有两层循环的时候,"break 1"跳出内循环; " break 2"跳出外循环

#!/bin/bash
num=10
for ((i=1;i<=10;i++))
do
	for((j=1;j<=5;j++))
	do
		
		if ((j==3))
			then
				break 1
			 else
				echo "$i $j"
			fi
	done
done

#!/bin/bash
num=10
for ((i=1;i<=10;i++))
do
	for((j=1;j<=5;j++))
	do
		
		if ((j==3))
			then
				break 2
			 else
				echo "$i $j"
			fi
	done
done

3.5 continue命令

实例:

#!/bin/bash
num=10
for ((i=1;i<=30;i++))
do
	if ((i>15 && i<25))
	then
				continue
	else
				echo "Number is $i"
	fi
done

3.6 处理循环的输出

实例

#!/bin/bash
num=10
for ((i=1;i<=100;i++))
do
	echo "Number is $i"

done > result.txt

#!/bin/bash
num=10
for ((i=1;i<=100;i++))
do
	echo "Number is $i"

done | grep "5"

四. 变量的高级用法

4.1 变量替换和测试

变量替换

语法 含义
${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除
${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除
${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除
${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除
${变量名/旧字符串/新字符串} 变量内容符合旧字符串规则,则第一个旧字符串会被新字符串取代
${变量名//旧字符串/新字符串} 变量内容符合旧字符串规则,则全部的旧字符串会被新字符串取代

实例

变量测试

实例

4.2 字符串处理

计算字符串长度

方法一:
${#string}

方法二:
expr length "$string"  #string如果有空格,则必须加双引号

获取子串在字符串中的索引位置

语法

expr index $string $substring

$substring会被切割成字符,比如orl被切割成o,r,l,分别查找字符,哪个字符最先找到就会返回那个字符的位置,l最靠前,位置为3,返回3

计算子串长度

expr match $string substr


$string会从头开始匹配子串,不能从中间匹配

抽取子串

方法一:
${string:position}                       #从string中的position开始

方法二:
${string:position:length}                 #从position开始,匹配长度为length

方法三:
${string:-(position)}                       #从右边开始匹配 

方法四:
${string:(position)}                      #从左边开始匹配 

方法五:
expr substr $string $position $length     #从position开始,匹配长度为length


练习

需求描述:
变量string=“Bigdata process framework is Hadoop,Hadoop is an open source project” 执行脚本后,打印输出string字符串变量,并给出用户以下选项:

  • 打印string长度
  • 删除字符串中所有的Hadoop
  • 替换第一个Hadoop为Mapreduce
  • 替换全部Hadoop为Mapreduce

用户输入数字1|2|3|4,可以执行对应项的功能;输入qlQ则退出交互模式

脚本:

read命令用于从标准输入中读取输入单行
 -a:将分裂后的字段依次存储到指定的数组中,存储的起始位置从数组的index=0开始。
 -d:指定读取行的结束符号。默认结束符号为换行符。
 -n:限制读取N个字符就自动结束读取,如果没有读满N个字符就按下回车或遇到换行符,则也会结束读取。
 -N:严格要求读满N个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束。其中换行符或回车算一个字符。
 -p:给出提示符。默认不支持"\n"换行,要换行需要特殊处理,见下文示例。例如,"-p 请输入密码:"
 -r:禁止反斜线的转义功能。这意味着"\"会变成文本的一部分。
 -s:静默模式。输入的内容不会回显在屏幕上。
 -t:给出超时时间,在达到超时时间时,read退出并返回错误。也就是说不会读取任何内容,即使已经输入了一部分。
 -u:从给定文件描述符(fd=N)中读取数据。
#!/usr/bin/env bash

string="Bigdata process framework is Hadoop,Hadoop is an open source project"

function tips_info
{ 
        
	echo "******************************************"
	echo "*** (1) 打印string长度"
	echo "*** (2) 在整个字符串中删除Hadoop"
	echo "*** (3) 替换第一个Hadoop为Mapreduce"
	echo "*** (4) 替换全部Hadoop为Mapreduce"
	echo "******************************************"
}

function print_len
{ 
        
	if [ -z "$string" ];then
		echo "Error,string is null"
		exit 1
	else
		echo "${#string}"
	fi
}

function del_hadoop
{ 
        
	if [ -z "$string" ];then
		echo "Error,string is null"
		exit 1
	else
		echo "${string//Hadoop/}"
	fi
}

function rep_hadoop_mapreduce_first
{ 
        
	if [ -z "$string" ];then
		echo "Error,string is null"
		exit 1
	else
		echo "${string/Hadoop/Mapreduce}"
	fi
}

function rep_hadoop_mapreduce_all
{ 
        
        if [ -z "$string" ];then
                echo "Error,string is null"
                exit 1
        else
                echo "${string//Hadoop/Mapreduce}"
        fi
}


while true
do

echo "【string=\"$string\"】"
tips_info
read -p "Pls input your choice(1|2|3|4|q|Q):" choice
case "$choice" in
	1)
		echo
		echo "Length Of String is: `print_len`"
		echo
		continue
		;;
	2)
		echo
		echo "删除Hadoop后的字符串为:`del_hadoop`"
		echo
		;;
	3)
		echo 
		echo "替换第一个Hadoop的字符串为:`rep_hadoop_mapreduce_first`"
		echo
		;;
	4)
		echo 
                echo "替换第一个Hadoop的字符串为:`rep_hadoop_mapreduce_all`"
                echo
		;;
	q|Q)
		exit 0
		;;
	*)
		echo "error,unlegal input,legal input only in { 1|2|3|4|q|Q }"
		continue	
		;;
esac
done

4.3 命令替换

语法格式

方法一
`command`

方法二
$(command)

$(())两个括号用来进行,包括加减乘除数据运算,引用变量前面可以加$,也可以不加$

案例

获取系统的所有用户并输出

cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。

如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。

参数:

    -b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
    -c :以字符为单位进行分割。
    -d :自定义分隔符,默认为制表符。
    -f :与-d一起使用,指定显示哪个区域。
    -n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的范围之内,该字符将被写出;否则,该字符将被排除
#!/bin/bash
index=1

for user in `cat /etc/passwd | cut -d ":" -f 1`
do
	元器件数据手册、IC替代型号,打造电子元器件IC百科大全!
          

相关文章