shell编程:

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.文件的扩展名必须是.sh
2.文件的首行必须是#!	指定script的运行shell环境(即脚本解释器)
	例如:#!/bin/bash
3.脚本里的行注释符号为#
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 $a
9
[root@qianfeng01 ~]# echo $str
hello qianfeng
[root@qianfeng01 ~]# a=10
[root@qianfeng01 ~]# echo $a
10

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

[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 $aa
9
-------------------------------------------------------------------------------------
[root@qianfeng01 ~]# bb=`expr 4+5`
[root@qianfeng01 ~]# echo $bb
4+5
[root@qianfeng01 ~]# bb=`expr 4 + 5`
[root@qianfeng01 ~]# echo $bb
9

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

[root@qianfeng01 ~]# echo $a
hello world

4.变量叠加

#变量叠加,就是将两个字符串变量的值叠加在一起,类似于Java中的字符串拼接操作
[root@qianfeng01 ~]# a=123
[root@qianfeng01 ~]# echo $a
123
[root@qianfeng01 ~]# b="$a"456
[root@qianfeng01 ~]# echo $b
123456
[root@qianfeng01 ~]# e=${a}456
[root@qianfeng01 ~]# echo $e
123456
------------------------------------------------------------------------------------
#单引号和双引号的区别:
#现象:单引号里的内容会全部输出,而双引号里的内容会有变化
#原因:单引号会将所有的特殊字符脱意
[root@qianfeng01 ~]# num=10
[root@qianfeng01 ~]# sum="$num hehe"
[root@qianfeng01 ~]# echo $sum
10 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 $a
22
[root@qianfeng01 bin]# echo 'echo $A' >> test.sh
[root@qianfeng01 bin]# echo $a
22
[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文件中的定义

位置参数变量:

变量描述
$nn为数字表示第几个参数,$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  + 5
8
[root@qianfeng01 ~]# expr 3 - 5
-2
[root@qianfeng01 ~]# expr 3 / 5
0
[root@qianfeng01 ~]# expr 3 % 5
3
[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/bash
var='welcome to China'
length1=${#var}
length2=$(expr length "${var}")
length3=`expr length "$var"`
echo $length1
echo $length2
echo $length3  

shell数组:

1.数组的使用规则:

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

2.数组的定义:

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

3.读取数组:

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

echo ${citys[0]}
echo ${hobby[*]}
echo ${#hobby[@]}
[root@qianfeng01 ~]# bash test3.sh
chen
read film music
3

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 filenameand,两个检测都成立,返回true
test -r filename -o -x filenameor,只要有一个成立,就返回true
test ! r filename

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

2.判断符号[]

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


条件控制:

if条件语句-单分支

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

注意事项:

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

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

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

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

if条件语句-多分支

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

示例:

编写⼀个坐⻋脚本,要求:
脚本名字: home.sh
逻辑: 从外⾯传⼊⼀个参数,根据参数判断: 1. 坐⻜机,2. 坐⽕⻋,3. 坐⽕箭,4.
不回了

[root@qianfeng01 myShell]# cat test6.sh
#!/bin/bash
read -p "please input your choice:" choice
if [ $choice == 1 ]   #当然也可以使用test,括号中的内容换成 $choice -eq 1
then
        echo "坐飞机"
elif [ $choice == 2  ]
then
        echo "坐火车"
elif [ $choice == 3  ]
then
        echo "坐火箭"
else
        echo "不回了"
fi

case:

在java中我们学过了switch-case这种结构,这种结构, 我们可以捕获一个变量的值,对这个变量取到的某些值进行不同的处理,在Shell中 ,也有类似的结构,就是case
case命令是一个多分支的if/else命令,case变量的值用来匹配value1,value2,value3等不同的值
-匹配到之后,执行后面的命令,直到遇到双分号为止
-类似于if命令,case命令使用esac作为终止符
-case行尾必须为单词in
-每个分支必须以右括号结束
-匹配模式中可以使用方括号表示一个连续的范围,如[0-9];使用“|”表示或

#case的格式
CMD=$1
case $CMD in
-------case行尾必须为 变量 in 表示捕获这个变量的值
start)
-------需要匹配到的值,需要以右括号作为结尾
	echo "starting"
匹配到之后,执行的逻辑语句,即一个分支
	;;
--------一个分支的逻辑,需要以;;作为结束,不会向下穿透
stop)
	echo "stopping"
	;;
*)
---------*表示以上的分支都不满足的情况,类似于switch-case中的default
	echo "please using start|stop"
	;;
esac
---------case语句,需要使用esac结束
#!/bin/bash
case $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 3
do
	echo $N
done
--------------------------------------------------------------------------------
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 $i
done
--------------------------------------------------------------------------------
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
	command
done

第二种:

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


第二种:

```shell
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:执行并显示脚本内容

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值