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