shell编程:
发布日期:2021-07-22 10:54:28 浏览次数:2 分类:技术文章

本文共 11964 字,大约阅读时间需要 39 分钟。

shell编程:

shell的概念介绍:

1.1命令解释器:

shell是命令解释器(command interpreter),是Unix操作系统的用户接口,程序从用户接口得到的输入信息,shell将用户程序及其输入翻译成操作系统内核(kernel)能够识别的指令,并且操作系统内核执行完将返回的输出通过shell在呈现给用户,下图所示用户,shell,和操作系统之间的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L8Ujhb0I-1624872441787)(C:\Users\16326\Desktop\dayHomework\QQ截图20210624213540.png)]

(一个系统可以存在多个shell)

操作系统内核(kernal)与shell是独立的套件,而且都可以被替换;不同的操作系统使用不同的shell;同一个kernal之上可以使用不同的shell,也可以查看当前的shell是哪种:

Shell脚本:

Shell也是一门编程语言,即Shell脚本,在此脚本中,我们可以使用一些编程语法来进行一些任务操作,如:变量,类型,分支结构,循环结构,数组,函数等语法,在shell脚本中,必须指定一种shell命令解释器

Shell编程规范:

1.脚本文件的结构:

1.文件的扩展名必须是.sh2.文件的首行必须是#!	指定script的运行shell环境(即脚本解释器)	例如:#!/bin/bash3.脚本里的行注释符号为#4.指令,选项,参数之间即使有多个空格仍然会被视为一个空格5.tab键形成的空白也视为一个空格键6.空白行会被忽略

2.脚本文件的执行;

1.使用bash程序调用执行,只需要有读权限即可2.直接写script,必须要有rx权限才行3.借助变量Path功能

3.Shell的变量:

3.1变量的用法:

1.变量的命名规则:	-命令只能使用英文字母,数字,下划线,首个字符不能以数字开头	-字母习惯使用大写	-中间不能有空格	-不能使用标点符号	-不能使用bash里的关键字,可以使用help命令查看保留关键字2.变量的使用规则:	-直接定义变量名称,没有类型需要强调(类似于数学中:x=1,y=2,z=x+y)	-赋值时,“=”前后不能有空格	-命令的执行结果赋值给变量时,使用反单引号	如time=`date`	-调用变量时,必须使用$	格式:$变量名	或者	${变量名}

3.2变量的分类:

Linux Shell中的变量可以分为三种变量:局部变量,环境变量,特殊变量,可以通过set命令查看系统中存在的所有变量局部变量:也就是用户自定义的变量,在脚本中或者命令行中定义环境变量:保存和系统操作环境相关的数据,$HOME,$PWD,$SHELL,$USER等特殊变量:	一种是位置参数变量:主要用来向脚本中传递参数或者数据,变量名不能自定义,变量作用固定	一种是预定义变量:是bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的

3.3局部变量:

用户自定义的变量由字母或者下划线开头,有字母,数字,下划线组成,并且大小写字母意义不同,变量名长度没有限制

1.定义变量:习惯上用大写字母来命名变量,变量名以字母表示的字符开头,不能用数字

2.调用变量:

​ 2.1在使用变量的时候,要在变量名前加上前缀"$"

​ 2.2使用echo,命令查看变量值

3.变量赋值:

​ 第一种:定义时赋值:

#变量=值#注意:在上述的定义方式中,等号两边不能有空格[root@qianfeng01 ~]# str="hello qianfeng"[root@qianfeng01 ~]# a=9[root@qianfeng01 ~]# echo $a9[root@qianfeng01 ~]# echo $strhello qianfeng[root@qianfeng01 ~]# a=10[root@qianfeng01 ~]# echo $a10

​ 第二种:将第一个命令的执行结果给变量赋值

[root@qianfeng01 ~]# A=`ll -a`	--->反引号,运行里面的命令,并且把结果返回给变量A[root@qianfeng01 ~]# echo $A总用量 32 dr-xr-x---. 4 root root 159 6月 24 19:02 . dr-xr-xr-x. 17 root root 224 6月 24 15:30 .. -rw-------. 1 root root 1521 6月 22 18:55 anaconda-ks.cfg -rw-------. 1 root root 4691 6月 24 22:51 .bash_history -rw-r--r--. 1 root root 18 12月 29 2013 .bash_logout -rw-r--r--. 1 root root 176 12月 29 2013 .bash_profile -rw-r--r--. 1 root root 176 12月 29 2013 .bashrc -rw-r--r--. 1 root root 100 12月 29 2013 .cshrc drwxr-----. 3 root root 19 6月 24 19:02 .pki drwx------. 2 root root 57 6月 24 16:54 .ssh -rw-r--r--. 1 root root 129 12月 29 2013 .tcshrc-------------------------------------------------------------------------------------[root@qianfeng01 ~]# B=$(ll -a)   --->等价于反引号[root@qianfeng01 ~]# echo $B总用量 32 dr-xr-x---. 4 root root 159 6月 24 19:02 . dr-xr-xr-x. 17 root root 224 6月 24 15:30 .. -rw-------. 1 root root 1521 6月 22 18:55 anaconda-ks.cfg -rw-------. 1 root root 4691 6月 24 22:51 .bash_history -rw-r--r--. 1 root root 18 12月 29 2013 .bash_logout -rw-r--r--. 1 root root 176 12月 29 2013 .bash_profile -rw-r--r--. 1 root root 176 12月 29 2013 .bashrc -rw-r--r--. 1 root root 100 12月 29 2013 .cshrc drwxr-----. 3 root root 19 6月 24 19:02 .pki drwx------. 2 root root 57 6月 24 16:54 .ssh -rw-r--r--. 1 root root 129 12月 29 2013 .tcshrc-------------------------------------------------------------------------------------[root@qianfeng01 ~]# aa=$((4+5))[root@qianfeng01 ~]# echo $aa9-------------------------------------------------------------------------------------[root@qianfeng01 ~]# bb=`expr 4+5`[root@qianfeng01 ~]# echo $bb4+5[root@qianfeng01 ~]# bb=`expr 4 + 5`[root@qianfeng01 ~]# echo $bb9

​ 第三种:将一个变量的值赋给另一个变量:

[root@qianfeng01 ~]# echo $ahello world

4.变量叠加

#变量叠加,就是将两个字符串变量的值叠加在一起,类似于Java中的字符串拼接操作[root@qianfeng01 ~]# a=123[root@qianfeng01 ~]# echo $a123[root@qianfeng01 ~]# b="$a"456[root@qianfeng01 ~]# echo $b123456[root@qianfeng01 ~]# e=${a}456[root@qianfeng01 ~]# echo $e123456------------------------------------------------------------------------------------#单引号和双引号的区别:#现象:单引号里的内容会全部输出,而双引号里的内容会有变化#原因:单引号会将所有的特殊字符脱意[root@qianfeng01 ~]# num=10[root@qianfeng01 ~]# sum="$num hehe"[root@qianfeng01 ~]# echo $sum10 hehe[root@qianfeng01 ~]# sum2='$num hehe'[root@qianfeng01 ~]# echo $sum2$num hehe

删除变量:

#删除之前已经定义过了的变量,之后就无法再使用这个变量了#撤销变量a[root@qianfeng01 ~]# unset a#声明静态的变量 b=2,不能使用unset[root@qianfeng01 ~]# readonly b=2[root@qianfeng01 ~]#  unset b-bash: unset: b: 无法反设定: 只读 variable

注意事项:

关于局部变量的作用域问题,用户自定义的局部变量,作用仅限于当前的shell环境,仅在当前的shell示例中有效,其他shell启动的程序不能访问局部变量

[root@qianfeng01 bin]# echo '#!bin/bash' > test.sh[root@qianfeng01 bin]# a=22[root@qianfeng01 bin]# echo $a22[root@qianfeng01 bin]# echo 'echo $A' >> test.sh[root@qianfeng01 bin]# echo $a22[root@qianfeng01 bin]# bash test.sh#打印结果为空,因为bash会开启一个新的shell进程

环境变量:

用户自定义的局部变量,只能在当前的shell和其所有的子shell中生效,如果把环境变量写进相应的配置文件,那么这个环境变量就会在所有的shell中生效

作用域:当前的shell以及所有的子shell

声明变量:export 变量名=变量值

定义环境变量的常见配置文件:

1./etc/profile ----> 针对系统所有的用户生效,此文件应用于所有用户每次登录系统时的环境变量定义,每次用户登陆的时候,都会加载这个文件

2. H O M E / . b a s h p r o f i l e − − − − − > 针 对 于 特 殊 的 用 户 生 效 , HOME/.bash_profile ----->针对于特殊的用户生效, HOME/.bashprofile>HOME为用户的宿主目录,当这个用户登录的时候,首先加载/etc/profile文件中的定义,再加载$HOME/.bash_profile文件中的定义

位置参数变量:

变量 描述
$n n为数字表示第几个参数,$0表示命令本身,$1- 9 表 示 第 1 到 第 9 个 参 数 , 10 以 上 的 参 数 需 要 使 用 大 括 号 包 含 , 例 如 9表示第1到第9个参数,10以上的参数需要使用大括号{}包含,例如 91910使{10}
$* 代表命令行中的所有参数,把所有参数看成一个整体,以“$1 2... 2... 2...n”的形式输出所有参数
$@ 代表命令行中的所有参数,把每个参数区别对待,以"$1"" 2 " . . . . " 2"...." 2"...."n"的形式输出所有参数
$# 参数的个数

@ 和 @和 @*的区别:

​ 1.他们都表示传递给函数或者脚本的所有参数,不被双引号包含时,都以"$1"" 2 " . . . " 2"..." 2"..."n"的形式输出所有参数

​ 2.当他们被双引号包含时

​ 2.1.“$*”会将所有的参数作为一个整体,以$1 $2 … $n的形式输出所有参数

​ 2.2“$@”会将各个参数分开,以"$1"" 2 " . . . " 2"..." 2"..."n"的形式输出所有参数

预定义变量:

变量 描述
$? 执行上一个命令的返回值,执行成功,返回0;执行失败,返回非0
$$ 当前进程的进程号(PID),即当前脚本执行时生成的进程号
$! 后台运行的最后一个进程的进程号(PID),最后一个被放入后台执行的进程

read命令:

说明:read命令,可以从控制台读取用户输入的内容,并且给指定的变量进行赋值命令的基本格式为:read [option] variable常用option:	-p:提示语句,在输入之前给用户提示信息	-n:显示输入的字符数量,到达这个数量的字符的时候,会自动地停止输入	-t:等待时间,单位为秒,当到达这个等待时间的时候,会自动地结束输入,并且不会读取任何输入的内容!	即,输入操作且回车,必须在执行的时间内完成	-s:隐藏输入的内容,在控制台上不显示任何输入的内容,常见于密码输入

注意事项:

1.在输入的时候,如果输入错了需要删除的时候,请使用ctrl+delete

2.符号不要输入中文

3.变量与之前的内容需要保持有空格


运算:

1.expr:

格式:expr m + n 或者 $((m+n))	注意expr与运算符和变量之间要有空格sum=$((m+n))	中=与$之间没有空格expr命令:对整数型变量进行算术运算(注意:运算符前后必须要有空格)
[root@qianfeng01 ~]# expr 3  + 58[root@qianfeng01 ~]# expr 3 - 5-2[root@qianfeng01 ~]# expr 3 / 50[root@qianfeng01 ~]# expr 3 % 53[root@qianfeng01 ~]# expr 3 \* 5  ------>*具有特殊含义,代表任意字符,所以需要使用转义字符\15[root@qianfeng01 ~]# echo $((3+5))8[root@qianfeng01 ~]# echo $((3-5))-2[root@qianfeng01 ~]# echo $((3/5))0[root@qianfeng01 ~]# echo $((3%5))3[root@qianfeng01 ~]# echo $((3*5))15

2. ( ) 与 ()与 (){}的区别

$()的用途和反引号``一样,用来表示优先执行的命令[root@qianfeng01 ~]# echo $(ls /root)anaconda-ks.cfg${
}作用是用来取变量echo ${PATH}$((运算内容)) 用于数字运算

字符串

1.字符串的脚本用法:	字符串不能单独使用,必须要配合变量	字符串可以使用单引号[' '],也可以使用双引号[" "],也可以不使用引号	单引号内的任意字符没有任何意义,都回原样输出	单引号内使用变量是无效的,单引号内不能出现单引号	双引号内可以使用变量	双引号内可以使用转义字符	在字符串拼接操作的时候我们可以进行无缝拼接,或者是在双引号里使用变量
2.字符串的长度	可以使用${#variable}或者expr length "${variable}"示例:#!/bin/bashvar='welcome to China'length1=${#var}length2=$(expr length "${var}")length3=`expr length "$var"`echo $length1echo $length2echo $length3

shell数组:

1.数组的使用规则:

在/bin/bash这个shell中,只有一维数组的概念,并且不限制数组的长度数组的元素是从0开始的获取数组的元素要使用下标下标使用不当,会报错

2.数组的定义:

定义格式:variable=(值1,值2,... 值3)注意:元素之间除了使用空格作为分隔符,还可以使用换行符或者name[0]=值1name[1]=值2...name[n]=值n

3.读取数组:

${variable[index]}		读取index索引上的元素${variable[*]}			读取所有元素${#variable[*]}或者${#variable[@]}		获取数组的长度
[root@qianfeng01 ~]# cat test3.sh#!/bin/bashcitys=(chen heng wen tian yuan)hobby[0]=readhobby[1]=filmhobby[2]=musicecho ${citys[0]}echo ${hobby[*]}echo ${#hobby[@]}[root@qianfeng01 ~]# bash test3.shchenread film music3

test测试命令:

文件检测类型:

test -e filename 检测filename是否存在
test -d filename 检测filename是不是目录
test -f filename 检测filename是不是普通文件
test -L filename 检测filename是不是软链接文件

文件属性检测:

test -r filename 检测filename是否有可读权限
test -w filename 检测filename是否有可写权限
test -x filename 检测filename是否有执行权限

两个文件的比较:

test file1 -nt file2 检测file1是否比file2新
test file1 -ot file2 检测file1是否比file2旧
test file1 -ef file2 检测file1和file2是否为同一文件

两个整数进行比较:

test n1 -eq n2 检测n1与n2是否相等
test n1 -ne n2 检测n1与n2是否不等
test n1 -gt n2 检测n1是否大于n2(greater than)
test n1 -lt n2 检测n1是否小于n2(less than)
test n1 -ge n2 检测n1是否大于等于n2
test n1 -le n2 检测n1是否小于等于n2

里那个字符串进行比较:

test -z string 检测string是否为空
test -n string 检测string是否不为空 -n 可以省略
test string1 == string2 检测string1与string2是否相等
test string1 != string2 检测string1与string2是否不相等

多条件连接:

test -r filename -a -x filename and,两个检测都成立,返回true
test -r filename -o -x filename or,只要有一个成立,就返回true
test ! r filename

1.通常来说test命令不单独使用,而是与if语句连用,或者是放在循环结构中

2.判断符号[]

​ 除了好用的test之外,我们还可以使用中括号来进行检测条件是否成立


条件控制:

if条件语句-单分支

if [条件判断]then	条件成功时执行逻辑fi
if [条件判断];then	条件成立时的逻辑fi
#!/bin/basha=$1if($a == "true")then        echo "hello world"fi

注意事项:

1.if语句需要使用fi结尾,和一般的语言使用大括号结尾不同

2.[条件判断] 就是用test命令进行判断,所以中括号和条件判断之间必须要有空格

3.then后面跟符合条件之后执行的程序,可以放在[]之后,用;分隔,也可以换行写入,就不需要;了

4.if与中括号之间必须要有空格

if条件语句-多分支

if [条件判断1]then	当条件判断1成立之时,执行程序1elif [条件判断2]then	当条件判断式2成立之时,执行程序2else 	当所有条件都不满足时,执行此程序fi

示例:

编写⼀个坐⻋脚本,要求:脚本名字: home.sh逻辑: 从外⾯传⼊⼀个参数,根据参数判断: 1. 坐⻜机,2. 坐⽕⻋,3. 坐⽕箭,4.不回了[root@qianfeng01 myShell]# cat test6.sh#!/bin/bashread -p "please input your choice:" choiceif [ $choice == 1 ]   #当然也可以使用test,括号中的内容换成 $choice -eq 1then        echo "坐飞机"elif [ $choice == 2  ]then        echo "坐火车"elif [ $choice == 3  ]then        echo "坐火箭"else        echo "不回了"fi

case:

在java中我们学过了switch-case这种结构,这种结构, 我们可以捕获一个变量的值,对这个变量取到的某些值进行不同的处理,在Shell中 ,也有类似的结构,就是casecase命令是一个多分支的if/else命令,case变量的值用来匹配value1,value2,value3等不同的值-匹配到之后,执行后面的命令,直到遇到双分号为止-类似于if命令,case命令使用esac作为终止符-case行尾必须为单词in-每个分支必须以右括号结束-匹配模式中可以使用方括号表示一个连续的范围,如[0-9];使用“|”表示或
#case的格式CMD=$1case $CMD in-------case行尾必须为 变量 in 表示捕获这个变量的值start)-------需要匹配到的值,需要以右括号作为结尾	echo "starting"匹配到之后,执行的逻辑语句,即一个分支	;;--------一个分支的逻辑,需要以;;作为结束,不会向下穿透stop)	echo "stopping"	;;*)---------*表示以上的分支都不满足的情况,类似于switch-case中的default	echo "please using start|stop"	;;esac---------case语句,需要使用esac结束
#!/bin/bashcase $1 in"1")        echo "周一";;"2")        echo "周二";;"3")        echo "周三";;"4")        echo "周四";;"5")        echo "周五";;"6")        echo "周六";;"7")        echo "周日";;esac

循环:

for循环:

for循环命令用来在一个列表条目中执行有限次数的命令 比如:你可能会在一个姓名列表或者文件列表中循环执行同一个命令for命令后紧跟着一个自定义变量,一个关键字in和一个字符串列表(可以是变量)第一次执行for循环的时候,字符串列表的第一个字符串会赋值给自定义变量,然后执行循环命令,直到遇到done语句;第二次执行for循环的时候,会右推字符串列表中的第二个字符串给自定义变量以此类推,知道字符串列表遍历完

方式一:

for N in 1 2 3do	echo $Ndone--------------------------------------------------------------------------------for N in 1 2 3 ;do	echo $N;done--------------------------------------------------------------------------------for N in {
1..3};do echo $N;done--------------------------------------------------------------------------------for N in {
1,2,3};do echo $N;done

方式二:

for((i  =  0;  i <= 5; i++))do	echo $idone--------------------------------------------------------------------------------for((i = 0; i <= 5; i++));do 	echo $i ;done

while循环:

while命令根据紧跟其后的命令(command)来判断是否执行while循环,当command执行后的返回值(exit status)为0时,则执行while循环语句块,直到遇到done语句,然后再返回到while命令,判断command的返回值,当得到返回值为非0时,则终止while循环

第一种:

while [ expression ]do	commanddone

第二种:

while((expression))do	command	...done

函数:

1.函数代表着一个或者一组命令的集合,表示一个功能模块,常用于模块化编程2.以下是关于函数的一些重要说明:	在Shell中,函数必须先定义,再调用	使用return value来获取函数的返回值	函数在当前shell中执行,可以使用脚本中的变量
函数名(){
命令一 命令二 return 返回值变量}结构:[ function ] funname [ () ]{
action; [return int;]}function start() / function start / start()

注意事项:

如果返回值后面没有(),在函数名和{之间,必须要有空格以示区分。函数返回值,只能通过$?,系统变量获取,可以显示加:return 返回值如果不加return 将以最后一条命令的运行结果作为返回值return后面的内容以字符串的形式写入,但是执行时会自动转换成数值类型,范围:数值n[0-255]

脚本测试:

-x:执行脚本,并显示所有变量的值

-n:不执行脚本,只是检查语法,将返回所有语法错误,例如函数没有正确闭合等

-v:执行并显示脚本内容

on ]

do
command
done

第二种:```shellwhile((expression))do	command	...done

函数:

1.函数代表着一个或者一组命令的集合,表示一个功能模块,常用于模块化编程2.以下是关于函数的一些重要说明:	在Shell中,函数必须先定义,再调用	使用return value来获取函数的返回值	函数在当前shell中执行,可以使用脚本中的变量
函数名(){
命令一 命令二 return 返回值变量}结构:[ function ] funname [ () ]{
action; [return int;]}function start() / function start / start()

注意事项:

如果返回值后面没有(),在函数名和{之间,必须要有空格以示区分。函数返回值,只能通过$?,系统变量获取,可以显示加:return 返回值如果不加return 将以最后一条命令的运行结果作为返回值return后面的内容以字符串的形式写入,但是执行时会自动转换成数值类型,范围:数值n[0-255]

脚本测试:

-x:执行脚本,并显示所有变量的值

-n:不执行脚本,只是检查语法,将返回所有语法错误,例如函数没有正确闭合等

-v:执行并显示脚本内容

转载地址:https://blog.csdn.net/m0_56433040/article/details/118308454 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Linux常用命令
下一篇:软件管理机制:

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月21日 04时26分10秒