shell是一个命令解释器,它为用户提供了一个向linux内核发送请求,以便运行,程序的界面系统级程序,用户可以用shell来启动,挂起,停止甚至是编写一些程序,看一个示意图

脚本是以#!/bin/bash开头,具有可执行权限

[root@localhost ~]# mkdir /root/shcode
[root@localhost ~]# cd /root/shcode/
[root@localhost shcode]# ls
[root@localhost shcode]# vim hello.sh 输入下面的必须以#!/bin/bash 开头,
#!/bin/bash
echo "hello.world"
[root@localhost shcode]# chmod u+x hello.sh
[root@localhost shcode]# ./hello.sh
hello.world
[root@localhost shcode]# chmod u-x hello.sh
[root@localhost shcode]# sh hello.sh
 
#方式1输入脚本的绝对路径或相对路径,首先要赋予脚本的+x权限,再执行脚本,
#方式2,sh+脚本,
#说明,不用赋予脚本+x权限,直接执行即可

Shell的变量,
linux Shell中的变量分为,系统变量和用户自定义变量。
系统变量:$HOME,$PWD,$SJELL,$USER等等,比如;echo $HOME等等,
显示当前shell中所有变量:set
基本语法:定义变量: 变量名=值 (没有空格)
撤销变量:unset 变量,
声明静态变量:readonly 变量,注意:不能unset
快速入门
定义变量A
撤销变量A
声明静态变量的B=2 不能unset
可以把变量提升为全局环境变量,可提供其他shell程序 使用该案例后面讲

#!/bin/bash
#定义变量A
A=100
#输出变量需要加上$
echo A=$A
echo “A=$A”
#撤销变量
unset A
echo "A=$A"
#声明静态变B=2 不能unset
readonly B=2
echo "B=$B"
#unset B 不能unset 静态变量不能unset

变量名称可以有字母,数字,和下划线组成,但是不能以数字开头,5A=200(x)
2等会两侧不能有空格
3变量名称一般习惯为大写,
将命令的返回值,赋给变量,
A=date反引号,运行里面的命令,并把结果返回给变量A
A=$(date)等价于反引号
位置参数变量,
$ n 为数字,$)代表命令本身,$1-$(代表第一道第九个参数,十以上,的参数,十以上的参数需要大括号包好,如$10
$* (功能描述这个变量代表命令行中所有参数,$*把所有参数,看成一个整体。)
$@(这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待,)
¥#(这个变量代表命令行中所有参数的个数)
案例:编写一个shell脚本position.sh 在脚本中获取到命令行的各个参数信息。

[root@localhost ~]# vim myshell.sh
[root@localhost ~]# cat myshell.sh
#!/bin/bash
echo "$0 $1 $2"
echo "所有的参数=$*"
echo "$@"
echo "参数的个数=$#"
[root@localhost ~]# chmod u+x myshell.sh
 [root@localhost ~]# ./myshell.sh 100  200 参数的结构。
./myshell.sh 100 200
所有的参数=100 200
100 200
参数的个数=2
 

预定义变量
就是shell设计者,事先已经定义好的变量,可以直接在shell 脚本中使用,

基本语法>$$功能描述:当前进程的进程号[PID])。 $符号(功能描述:后台运行的最后一个进程的进程号[PID])
$?(功能描述,最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令,正确执行;如果这个变量的值为非0
具体是哪个数,由命令自己来决定)则证明上一个命令执行不正确了
[root@localhost ~]# vim preVar.sh
#!/bin/bash
echo "当前执行的进程id=$$"
#以后台的方式运行一个脚本,并获取他的进程号
/root/shcode/myshell.sh  &
echo "最后一个后台方式运行的进程id=$!"
echo "执行的结果是=$?"
 
 [root@localhost ~]# chmod u+x preVar.sh
[root@localhost ~]# ll
total 630012
-rw-------. 1 root root      1259 Feb 13  2021 anaconda-ks.cfg
drwxr-xr-x  2 root root         6 Jan  3 16:30 docker
drwxr-xr-x  2 root root        26 Jan  6 16:41 dockerfile
drwxr-xr-x  2 root root        25 Jan  4 16:46 docker-test-volume
-rw-r--r--. 1 root root       106 Dec  9 02:33 hava.java
-rwxr-xr--. 1 root root        63 Sep 18 15:41 hellworld.sh
-rw-r--r--. 1 root root        30 Sep 18 14:54 hi.sh
-rw-r--r--. 1 root root    235657 Dec 17 19:58 javase8u211-later-archive-downloads.html
-rwxr--r--  1 root root        90 Jan  6 20:33 myshell.sh
-rw-r--r--  1 root root 644869837 Jan  2 20:45 mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
-rwxr--r--  1 root root       220 Jan  6 20:52 preVar.sh
-rw-r--r--  1 root root         0 Jan  3 14:59 --restart=alwys
drwxr-xr-x  2 root root        36 Jan  3 21:45 shcode
[root@localhost ~]# ./preVar.sh
当前执行的进程id=18277
最后一个后台方式运行的进程id=18280
执行的结果是=0
./preVar.sh: line 4: /root/shcode/myshell.sh: No such file or directory

运算符

在“$((运算式))”或“$[运算式]” 或者expr m + n //expression 表达式
注意expr 运算符间要有空格 如果希望将expr 的结果赋给某个变量,使用``
expr m - n
expr \*,/,% 乘,除,取余
应用案例,
计算(2+3)x4的值
[root@localhost ~]# ./oper.sh
resh1=20
[root@localhost ~]# cat oper.sh
#!/bin/bash
#计算(2+3)x4的值
#使用第一种方式
RES1=$(((2+3)*4))
echo "resh1=$RES1"
 
[root@localhost ~]# cat oper.sh
#!/bin/bash
#计算(2+3)x4的值
#使用第一种方式
RES1=$(((2+3)*4))
echo "resh1=$RES1"
#第二种 ,推荐使用
RES2=$[(2+3)*4]
echo "res2=$RES2"
#第三种
TEMP=`expr 2 + 3`
RES4=`expr $TEMP \* 4`
echo "temp=$TEMP"
echo "res4=$RES4"
 
[root@localhost ~]# ./oper.sh
resh1=20
res2=20
temp=5
res4=20

请求出命令行的两个参数,[整数的和]

[root@localhost ~]# vim oper.sh
[root@localhost ~]# ./oper.sh 20 50
resh1=20
res2=20
temp=5
res4=20
sum=70
[root@localhost ~]# cat oper.sh
#!/bin/bash
#计算(2+3)x4的值
#使用第一种方式
RES1=$(((2+3)*4))
echo "resh1=$RES1"
#第二种 ,推荐使用
RES2=$[(2+3)*4]
echo "res2=$RES2"
#第三种
TEMP=`expr 2 + 3`
RES4=`expr $TEMP \* 4`
echo "temp=$TEMP"
echo "res4=$RES4"
 
 
#案例二请求出命令行的两个参数,[整数的和]
SUM=$[$1+$2]
echo "sum=$SUM"
 
[root@localhost ~]#
条件判断
判断语句
基本语法
[ condition ] 注意condition 前后要有空格
非空返回true, ,可使用$?验证(0为true,>1为false)

应用案例,
[hsEdu] 返回 true
[] 返回false
[ condition ] && echo OK || echo notok 条件满足,执行后面的语句
条件判断
1) = 字符串比较
2) 两个整数的比较
-lt 小于 little equal
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
3)按照文件权限判断
-r 有读写、的权限
-w 有写的权限
-x 有执行的权限
4) 按照文件类型进行判断
-f 文件存在类型进行判断
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并是一个目录
应用实例,
案例1: "ok"是否等于"ok"
判断语句
案例2 23 是否大于等于22
判断语句
案例3 /root.shcode/aaa.txt 目录中的文件是否存在。
判断语句,

#案例1: "ok"是否等于"ok"

#判断语句 使用=

#案例2 23 是否大于等于22

#判断语句 使用-ge

#案例3 /root.shcode/aaa.txt 目录中的文件是否存在。

#判断语句, 使用-f

 

[root@localhost ~]# vim  ifdemo.sh

[root@localhost ~]# ./ifdemo.sh

equal

[root@localhost ~]# cat ifdemo.sh

#!/bin/bash

#案例1: "ok"是否等于"ok"

#判断语句 使用=

if [ "ok" = "ok" ]

then

        echo "equal"

fi

#案例2 23 是否大于等于22

#判断语句 使用-ge

#案例3 /root.shcode/aaa.txt 目录中的文件是否存在。

#判断语句, 使用-f

 

 

[root@localhost ~]# vim  ifdemo.sh

[root@localhost ~]# ./ifdemo.sh

equal

大于

[root@localhost ~]# cat ifdemo.sh

#!/bin/bash

#案例1: "ok"是否等于"ok"

#判断语句 使用=

if [ "ok" = "ok" ]

then

        echo "equal"

fi

#案例2 23 是否大于等于22

#判断语句 使用-ge

if [ 23 -ge 23 ]

then

        echo "大于"

fi

#案例3 /root.shcode/aaa.txt 目录中的文件是否存在。

#判断语句, 使用-f

 

[root@localhost ~]# vim  ifdemo.sh

[root@localhost ~]# ./ifdemo.sh    

equal

大于

./ifdemo.sh: line 18: unexpected EOF while looking for matching `"' 真的是,,,太严谨了,这语言中文的“”“”

./ifdemo.sh: line 20: syntax error: unexpected end of file

[root@localhost ~]# vim  ifdemo.sh

[root@localhost ~]# ./ifdemo.sh

equal

大于

./ifdemo.sh: line 18: unexpected EOF while looking for matching `"'

./ifdemo.sh: line 20: syntax error: unexpected end of file

[root@localhost ~]# vim  ifdemo.sh

[root@localhost ~]# ./ifdemo.sh

equal

大于

[root@localhost ~]# cat ifdemo.sh

#!/bin/bash

#案例1: "ok"是否等于"ok"

#判断语句 使用=

if [ "ok" = "ok" ]

then

        echo "equal"

fi

#案例2 23 是否大于等于22

#判断语句 使用-ge

if [ 23 -ge 23 ]

then

        echo "大于"

fi

#案例3 /root.shcode/aaa.txt 目录中的文件是否存在。

#判断语句, 使用-f

if [ -f /root/shcode/aaa.txt ]

then

        echo "存在"

fi

 

 

 

if判断,
基本语法
if [ 条件判断式 ]
then
代码
fi
或者。多分支
if [ 条件判断式 ]
then
elif [ 条件判断式 ]
then
代码
fi

注意,[ 条件判断式 ] 中括号和条件判断式之必须要有空格

[root@localhost ~]# vim ifCase.sh

[root@localhost ~]# ./ifCase.sh  70

及格了

[root@localhost ~]# ./ifCase.sh  35

“不及格”

[root@localhost ~]# cat ifCase.sh

#!/bin/bash

#编写一个shell程序,如果输入的参数,大于等于60,则输入“及格了”,如果小于60,则输入“不及格”

if [ $1 -ge 60 ]

then

        echo "及格了"

elif [ $1 -lt 60 ]

then

        echo “不及格”

fi

[root@localhost ~]#

case 语句

基本语法,

case  $ 变量名 in

"值1")

如果变量的值等于1,则执行程序1

;;

如果变量的值等于2,则执行程序2

;;

…省略其他分支…

如果变量的值都不是以上的值,则执行此程序

;;

esac

应用实例,testCase.sh

当命令参数是1 时,输出"周一",如果是2,输出"周二"。其他情况则输出 "other"

#!/bin/bash

#编写一个shell程序,如果输入的参数,大于等于60,则输入“及格了”,如果小于60,则输入“不及格”

if [ $1 -ge 60 ]

then

        echo "及格了"

elif [ $1 -lt 60 ]

then

        echo “不及格”

fi

 

[root@localhost ~]# vim testCase.sh

[root@localhost ~]# chmod u+o testCase.sh

[root@localhost ~]# chmod u+x testCase.sh

[root@localhost ~]# ./testCase.sh 1

周一

[root@localhost ~]# ./testCase.sh 2

周二

[root@localhost ~]# ./testCase.sh 4

other...

[root@localhost ~]# ./testCase.sh 5

other...

 

 

 

for 循环
基本语法
for 变量 in 值 1 值2 值3
do
程序/代码
done
基本语法2
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
案例打印命令,输入的参数,[这里可以看出$*和 $@的区别]
案例2 从1加到100的值输出显示

vim testFor.sh

[root@localhost ~]# vim testFor.sh

[root@localhost ~]# ./testFor.sh  100 200 300

num is 100 200 300

================================================

num is 100

num is 200

num is 300

[root@localhost ~]# cat testFor.sh

#/bin/bsha

#打印命令,输入的参数,[这里可以看出$*和 $@的区别]

# $* 把输入的参数,当作一个整体,所以只会输出一句

for i in "$*"

do

        echo "num is $i"

done

#使用 $来获取输入的参数,注意这时是分别对待,所以有几个参数,就会输出几句

echo "================================================"

for j in "$@"

do

        echo "num is $j"

done

 

 

 [root@localhost ~]# vim testFor2.sh

[root@localhost ~]# cat testFor2.sh

#!/bin/bash

#案例1; 从1加到100 的输出显示

#定义一个变量,SUM

SUM=0

for (( i=1; i<=100; i++ ))

do

# 写上你的业务代码

        SUM=$[$SUM+$i]

done

echo "总和SUM=$SUM"[root@localhost ~]# ./testFor2.sh

总和SUM=5050

 

                  

                  [root@localhost ~]# ./testFor2.sh  100

总和SUM=5050

[root@localhost ~]# ./testFor2.sh  10

总和SUM=55

[root@localhost ~]# ./testFor2.sh  105

总和SUM=5565

[root@localhost ~]# ./testFor2.sh  10555

总和SUM=55709290

[root@localhost ~]# cat testFor2.sh

#!/bin/bash

#案例1; 从1加到100 的输出显示,如何把100 做成一个变量

#定义一个变量,SUM

SUM=0

#for (( i=1; i<=100; i++ ))

for (( i=1; i<=$1; i++))

do

# 写上你的业务代码

        SUM=$[$SUM+$i]

done

echo "总和SUM=$SUM"

 

 

 

 

 

while 循环
while [ 条件判断式 ]
do
程序
done
注意,while

#/bin/bahs

#从命令行输入一个数字n,统计 1+...+n的值是多少

SUM=0  #变量初始化为0

i=0  #变量为0

while [ $i -le $1 ] #$i 小于等于1 

do

        SUM=$[$SUM+$i]  就进行循环操作

        #i自增

        i=$[i+1]

done

echo "执行结果=$SUM"

 

[root@localhost ~]# chmod u+x testwhile.sh

[root@localhost ~]# ./testwhile.sh 54

./testwhile.sh: line 5: [0: command not found

执行结果=0

[root@localhost ~]# vim testwhile.sh

[root@localhost ~]# ./testwhile.sh  54

执行结果=1485

[root@localhost ~]# ./testwhile.sh  5452

执行结果=14864878

 

read 读取控制台输入,
-p指定读取值时的提示符,
-p 指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不用再等待了。
参数,
变量:指定读取值得变量名
应用实例,
案例1:读取控制台输入一个num1值,
案例2:读取控制台输入一个num2值,在10秒内输入

#!/bin/bash

#案例1:读取控制台输入一个num1值

read -d"请输入控制台输入一个NUM1值=" NUM1

echo "请你输入的NUM1=$NUM1"

#案例2:读取控制台输入一个num2值,在10秒内输入。

read -t 10 -d"请输入控制台输入一个NUM1值=" NUM2

echo "请你输入的NUM1=$NUM2"

函数,shell编程,和其他的编程语言一样,也有系统函数,也可以自定义函数,在系统函数中basename 基本语法,
功能,basename 返回完整路径最后/ 的部分,常用于获取文件名
bashename [pathname] [suffix]
bashename [staring] [suffix] :bansename命令,会删掉所有的前缀,包括最后一个(/)字符,然后将字符串显示出来
选项,
suffix 为后缀,如果suffix 被指定,bashename 会将pathname或string中的suffix去掉
案例
请返回:/home/aaa/test.txt 的test.txt部分
basename /hoome/aaa/text.txt
dirname 基本语法,
返回完整路径最后/的前面部分,常用于,返回路径部分,
dirname 文件绝对路径, 从给定的包含绝对路径的文件名中去除文件名(非目录的部分)返回剩下的路径(目录的部分)

/home/aaa/test.txt的/home/aa
dirname /home/aaa/texs.txt

自定义函数
[ function ] funname[()]
{
Action;
[return int;]
}
调用直接写函数名:funame [值]
应用案例
案例1 计算输入连个参数的和(动态获取),getSum

#!/bin/bash

function getSum() {

    Sum=$[$n1+$n2]

    echo "和是$SUM"

}

 

#输入两个值

read -P "q请输入一个数n1=" n1

 

#调用自定义函数

getSUM $n1 $n2