一、shll简介
1、Shell是一种编程语言,该语言底层是C语言
2、Shell是一种解释型语言,和python类似
3、shell以后主要用于脚本编写,通过脚本实现自动化部署和调度
4、Shell是语言的统称,在Shell下面又细分了很多不同的Shell语言,默认用的Base Shell
5、Shell脚本文件的后缀是.sh,不过也可以不写
二、入门案例
2.1 编写简单的Shell脚本
创建存放shell文件的文件夹
mkdir /export/shell
vim hello.sh
编写shell脚本
#!/bin/bash #表示我们当前Shell使用的解释器是/bin/bash
echo "Hello World" #向控制台输出Hello World
2.2 shell的运行方式
-
方式1-脚本可以没有执行权限
sh hello.sh
-
方式2-脚本必须有执行权限
chmod +x hello.sh ./hello.sh #相对路径-指定脚本在当前目录 hello.sh #同上
-
方式3-脚本必须有执行权限
chmod +x hello.sh /export/shell/hello.sh #使用绝对路径指定脚本位置
-
------结论--------
#个人测试使用方式1 #生产环境中使用方式3
三、shell的数据类型
1、shell是弱类型语言,在定义变量时不需要指定类型
2、shell的数据类型只有两种
字符串类型 : hello 'hello' "hello"
整数型 : 123
四、shell的变量
4.1 用户自定义变量
- 定义变量
语法: 变量名=变量值
定义变量案例:
a=123 #"="左右两侧不能有空格。
s='hello'
注意:用户定义的变量只能在当前脚本中使用,或者在调用脚本中使用
- 使用变量
----正常赋值-------------
str1='hello'
str2='I Love China' #这里必须加引号,因为字符串中间有空格
echo $str1
echo ${str1}tom #这里必须要加{}
----特殊赋值1-------------
#!/bin/bash
echo "who are you?"
read name #从键盘获取变量的值
pwd_string=$(pwd) #将pwd命令的执行结果赋值给pwd_string变量
date_string=`date` #将date命令的执行结果赋值给date_string变量
echo "hello, $name"
echo $pwd_string
echo $date_string
----特殊赋值2-------------
#!/bin/bash
pwd #单独使用,可以指定pwd命令
str=$(pwd) #只能用于将pwd命令直接结果赋值给另外一变量
str=`pwd` #同上
echo $str
----只读变量-------------
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl #将变量声明为只读,以后不能修改
myUrl="http://www.runoob.com" #这里修改就会报错
----删除变量-------------
#!/bin/sh
myUrl="http://www.runoob.com"
unset myUrl #默认情况下,定义变量之后,直到shell脚本结束空间才会释放,加上该关键字,则立刻释放
echo $myUrl #报错
4.2 环境变量
-
特点
1、Linux的环境变量一般都是系统提前定义好的变量 2、Linux的环境变量用户也可以定义 3、Linux的环境变量可以在整个系统起作用 4、Linux的环境变量一般都是大写字母 5、Linux的环境变量一般在/etc/profile文件定义
-
环境量的查看
env
-
自定义环境变量
1、打开/etc/profile 2、在/etc/profile中定义变量,注意变量前边加上一个export关键字 export MY_ENV=helloxxxxxxxxxxxxxxxxxxx 3、刷新/etc/profile文件 source /etc/profile
-
使用环境变量
1、环境变量的使用和普通变量一模一样 echo $PWD str=$PWD
-
特殊变量
-
变量的内容
变量 解释 $# 命令行参数的个数 $n $1表示第一个参数,$2表示第二个参数,以此类推 $0 当前程序的名称 $? 前一个命令或许或函数的返回码 $* 以“参数1 参数2 。。。”形式保存所有参数 $$ 本程序的(进程ID号)PID -
实例
$0 $1 $2 $3 sh demo6.sh aaa bbb ccc #这里 $# 为 3 表示有3个参数 #这里 $? 为 上一条命令或者脚本返回的状态码 0 表示正常 非0 表示非正常
-
五、shell的字符串
-
自定格式
hello #最差 'hello' #一般 "hello" #最优 ------------------- #!/bin/sh a=xxx str1=hello str2='hello world---$a' #单引号会将包括的所有字符都当成字符串的一部分 str3="hello world---$a" #只有双引号才能识别字符串中包含的变量引用 echo $str1 #输出 echo $str2 #输出 hello world---$a echo $str3 #输出 hello world---xxx #结论----以后记着使用双引号
-
操作
1、转义 echo "hello\"world" #输出 hello\"world 2、求字符串长度 str="slkgsklgsksklgsklsgklk" echo ${#str} 3、字符串截取 string="敢于亮剑决不后退" echo ${string:2:3} #解释:2表示从2索引开始,3表示截取3个字符
六、shell的运算符
-
运算符类型
+ 加法 expr $a + $b
结果为 30。- 减法 expr $a - $b
结果为 -10。* 乘法 expr $a \* $b
结果为 200。/ 除法 expr $b / $a
结果为 2。% 取余 expr $b % $a
结果为 0。= 赋值 a=$b 将把变量 b 的值赋给 a。 == 相等。用于比较两个数字,相同则返回 true。 [ a == b ] 返回 false。 != 不相等。用于比较两个数字,不相同则返回 true。 [ a != b ] 返回 true。 -
例子
a=10 b=20 #求两个数的和 echo `expr $a + $b` #方式1-1,运算符两边必须留空格,而且变量必须加$ echo $(expr $a + $b) #方式1-2, 运算符两边必须留空格, 而且变量必须加$ echo $((a+b)) #方式2,运算符两边没有要求 echo $[a+b] #方式3,运算符两边没有要求 !!!!!
七、shell的流程控制语句
7.1 if语句
-
格式1
if condition then command1 command2 ... commandN fi
-
案例
#1)判断当前系统是否有多个ssh进程,如果有则打印true #!/bin/bash if [ $(ps -ef | grep -c "ssh") -gt 1 ] #注意[] 变量要留空格 then echo "true" fi #2)判断/media/cdrom文件是否存在,若不存在就去创建这个目录 #!/bin/bash DIR="/media/cdrom" if [ ! -e $DIR ] then mkdir -p $DIR fi
-
格式2
if condition then command1 command2 ... commandN else command fi
-
案例
#1) 根据年龄判断是否成年 #!/bin/bash read -p "请输入你的年龄:" age #键盘录入的提示符 if [ $age -ge 18 ] #等价与: if test $age -ge 18 then echo "你已经成年了!" else echo "你还没有成年!" fi #2)
-
格式3
if condition1 then command1 elif condition2 then command2 else commandN fi
-
案例
#1)以下实例判断两个变量是否相等: #!/bin/bash read -p "请输入a的值:" a read -p "请输入b的值:" b if [ $a -eq $b ] then echo "a 等于 b" elif [ $a -gt $b ] then echo "a 大于 b" elif [ $a -lt $b ] then echo "a 小于 b" else echo "没有符合的条件" fi #2)输入成绩,判断成绩“优”“良”“中” #!/bin/bash read -p "Enter your score(0-100):" n #-p参数表示给出提示信息 if [ $n -ge 85 ] && [ $n -le 100 ] ; then echo "优" elif [ $n -ge 70 ] && [ $n -le 84 ] ; then echo "良" elif [ $n -ge 60 ] && [ $n -le 69 ] ; then echo "中" else echo "差" fi
7.2 for语句
-
格式1
for 变量 in 值1 值2 值3… do 程序 done
-
案例
#!/bin/bash for i in 1 2 3 4 5 do echo "-----$i------" done -------------------------------- #!/bin/bash dir="" if [ -z $1 ] ; then dir=$PWD else dir=$1 fi for file in $(ls $dir) do echo "-------$file" done
-
格式2
for ((初始值;循环控制条件;变量变化)) do 程序 don
-
案例
#!/bin/bash for((i=1;i<=5;i++)) do echo "hello world---$i" done ------------求1-100和---------------- #!/bin/bash s=0 for((i=1;i<=100;i++)) do #s=$((s+i)) #s=$[s+i] let s+=i #加上let关键字,可以让shell的运算符和高级语言接轨 如: let s++ done echo "The sum of 1+2+..+100 is : $s"
7.3 while语句
-
格式
while 条件 do 程序 done
-
案例
--------1)输出1-5之间的数字------------ #!/bin/bash num=1 while [ $num -le 5 ] do echo $num let num++ done -------2)求1-100的和------------- #!/bin/bash i=1 sum=0 while [ $i -le 100 ] do let sum+=i let i++ done echo $sum
7.4 死循环
-
for的死循环
#!/bin/bash for((;;)) do echo "hello world" sleep 1 done
-
while死循环
# 格式1 #!/bin/bash while : do echo "hello world" sleep 1 done # 格式2 #!/bin/bash while true do echo "hello world" sleep 1 done
7.5 case 语句
-
格式
case 值 in 模式1) command1 command2 ... commandN ;; 模式2) command1 command2 ... commandN ;; esac
-
案例
#!/bin/bash read -p "请输入你的选择(1-3):" num case $num in 1) echo "你选择了1" ;; 2) echo "你选择了2" ;; 3) echo "你选择了3" ;; *) echo "你选择了其他" ;; esac ------case的穿透----------------- #!/bin/bash read -p "请输入你的选择(1-3):" num case $num in 1|2|3) echo "你选择了1或2或3" ;; *) echo "你选择了其他" ;; esac
7.6 break 和continue
这里的break和continue与java完全一样
八、Shell的函数
- 格式
[ function ] funname()
{
action;
[return int;] #这里的return不是用来返回函数的返回值,而是用来返回函数执行完的状态码($?)
}
- 定义
#----定义1:没有参数,没有返回值-----------
function func1(){
echo "Hello World"
}
调用函数:
func1
#----定义2:有参数,没有返回值-----------
function func2(){
echo "Hello World--$1--$2" #这里的$1和$2是向函数传入的参数
return 88
}
调用函数:
func2 aaa bbb
#----定义3:有参数,有返回值-----------
func3(){
sum=$[$1+$2]
echo $sum #shell的函数的返回值必须通过echo返回
}
调用函数:
result=$(func3 10 20)
echo "result=$result"
总结:
1、如果单独调用函数,则函数内部的echo会直接输出到控制台
func3
2、如果想要有返回值,则函数内部一般只写一个echo
result = $(func3 10 20)
- 函数的状态码
1、函数的状态码是通过return语句返回,一般return语句放在函数的最后
2、函数的状态码一般0表示正常,非0表示不正常
范围:0-255
举例;
func(){
if 条件1 ;then
return 1 #优秀
elif 条件2 : then
return 2 #良好
elif 条件3 : then
return 3 #一般
else
return 4 #较差
}
调用:
func
if [ $? -eq 1 ]
then
echo "你考试很优秀"
if [ $? -eq 2 ]
then
echo "你考试很良好"
九、shell的数组
#!/bin/bash
#1-数据的定义
array=("hello" "java" "mysql" "shell" "linux")
#2-访问数据元素
echo ${array[3]} #shell
#3-将数组所有元素转为字符串输出
echo ${array[*]}
#4-获取数组的长度
echo ${#array[*]}
#5-遍历数组-方式1
echo "----------方式1-------------"
for str in ${array[*]}
do
echo $str
done
echo "----------方式2-------------"
len=${#array[*]}
for((i=0;i<len;i++))
do
echo ${array[$i]}
done
十、shell的select语句
#!/bin/bash
echo "你要进行什么操作?"
PS3="请输入你选择:"
select var in "启动" "停止" "重启"
do
case $var in
"启动")
#执行启动命令
;;
"停止")
#执行停止命令
;;
"重启")
#执行重启命令
esac
break;
done
echo "正在进行 $var 操作..........."
sleep 3
十一、shell的脚本调入
-
1、编写func1.sh
#!/bin/bash MAX_VALUE=2147483648 R="Asia/beijing" func1(){ echo "我是func2.sh中的func1函数!" }
-
2、编写func2.sh
#!/bin/bash MAX_VALUE=2147483648 STR="Asia/beijing" func1(){ echo "我是func2.sh中的func1函数!" }
-
3、编写a.sh,导入func1.sh和func2.sh
注意当导入的多个脚本出现同名的变量或者函数,则以最后一次导入的脚本为主
#!/bin/bash #1-导入shell脚本 #方式1 . /export/shell/test/func1.sh . /export/shell/test/func2.sh #方式2 #source /export/shell/test/func.sh #2-使用脚本中内容 echo $MAX_VALUE echo $STR func1
十二、综合案例
12.1 案例1-猜字游戏
#!/bin/bash
#生成100以内的随机数 提示用户猜测 猜对为止
#random 系统自带,值为0-32767任意数
#随机数1-100
num=$[RANDOM%100+1]
#read 提示用户猜数字
#if判断
while :
do
read -p "计算机生成了一个 1‐100 的随机数,你猜: " cai
if [ $cai -eq $num ]
then
echo "恭喜,猜对了"
exit
elif [ $cai -gt $num ]
then
echo "不巧,猜大了"
else
echo "不巧,猜小了"
fi
done
12.2 案例2-一键安装jdk
#!/bin/bash
# 1.提示安装jdk
echo "现在开始安装jdk"
sleep 1 # 休眠1秒钟
# 2.删除centos自带的jdk
oldjava=$(rpm -qa | grep java )
for old in ${oldjava}
do
# echo $old
rpm -e --nodeps $old
done
# 3.创建安装目录/export/server, 进入安装目录
java_path="/export/server"
if [ ! -d $java_path ]
then
mkdir -p $java_path
fi
#4:解压jdk安装包
tar -xvf /export/software/jdk-8u241-linux-x64.tar.gz -C $java_path
# 6.设置环境变量
JAVA_HOME="/export/server/jdk1.8.0_241"
grep "JAVA_HOME" /etc/profile
if [ $? -ne 0 ]
then
# JAVA_HOME
echo "--------------JAVA_HOME------------------"
echo 'export JAVA_HOME=/export/server/jdk1.8.0_241' >> /etc/profile
# PATH
echo "--------------PATH------------------------"
echo 'export PATH=:$JAVA_HOME/bin:$PATH' >> /etc/profile
fi
# 7.加载环境变量
source /etc/profile
# 8.提示用户安装成功,查看jdk安装版本
echo "恭喜您,jdk安装成功!"
java -version
十三、shell的括号总结
$str #访问变量
${str} #访问变量
result=`ls` #执行shell命令,并得到命令执行结果
result=$(ls) #执行shell命令,并得到命令执行结果
result=$((1+2)) #执行数学运算
result=$[1+2] #执行数学运算
str=${array[*]} #求数组转为字符串
len=${#array[*]} #求数组长度
if [ ] #括号