654 rw-r-xr--
-w-r-x-wx 253
1.Shell是什么
比如:让你实现带逻辑功能的一段代码【变量、流程控制】 ---》 shell脚本
存储过程?create or replace produc A.. begin 逻辑过程 end call A()
关心如何编写shell脚本,可以执行出我们需要的结果即可!!!
shell应用场景:
1.重复性操作
2.自动化运维 ---》运维关注的比较多
3.定时任务执行 --》你的闹钟
4.后面会使用任务调度框架,Azkaban【DS】,也经常调用shell脚本!!
2.Shell的HelloWorld
shell脚本一般以.sh为扩展名,不加也可以,加上增加可读性!!
明确:在Linux,文件加不加扩展名其实无所谓!!!!
新建文件:01.sh
#!/bin/bash
echo "hello shell"
说明:# shell中#是注释
执行方式1:sh/bash 01.sh ---》类似我们的java、javac bin目录
执行方式2:/bin/bash 01.sh
问:sh和bash的关系
lrwxrwxrwx. 1 root root 4 6月 28 17:24 sh -> bash
执行方式3:
会报这个问题:
[root@hadoop101 shell]# ./01.sh #在当前目录,这种写法一般不写,而是绝对路径
-bash: ./01.sh: 权限不够
如何解决:给加+x执行权限
[root@hadoop101 shell]# /opt/shell/01.sh
【了解】如何查看shell解释器 cat /etc/shells
注意:mini版没有那个带界面的全!!!!
3.变量和常量【只读变量】+ 字符串拼接问题
重点:
1.变量会定义和取变量值 $变量名 ${变量名}
2.在`里面可以解析到Linux自带的命令,以及变量值,但是会报错!!
3.在双引号中,可以解析到变量的值,即使双引号中嵌套单引号也是ok的
4.双引号的转义问题: \"被引号括起来的内容\"
5.取变量值,要么使用双引号,要么不加符号!!!
类型比较灵活,不像java很严格;常用的是数字和字符串
java定义变量:int score=10; score="222" × sout() 给别的变量赋值
Java中常量定义:final int score = 10; score=20; ×
score=10
尤其注意:变量赋值的=两端不能有空格 abc12=11
命名规范:不能数字或者特殊符号开头
获取变量值:$score 或者 ${score}
新建02.sh,输出昨天的日期
#!/bin/bash
#date=`date -d '-1 day' +"%Y-%m-%d"` #这个必须要会,我们后面要使用!!!
#date='date'
date=`date`
#echo $date
echo ${date}
目的:掌握`、'、"的区别【蛮重要的】
使用双引用放在最外层,最靠谱!!!!!!!!!
区别1:在这些符号中使用Linux的命令,命令能否解析出来!!!
'':包裹的值,里面的命令会当成字符串出来,比如time='date',$time ---> date,而是不2021-06-30
单引号和双引号解析不出来
区别2:在拼接的时候,单引号和双引号的区别,能否拿到变量值
双引号的转义问题:\"
符号嵌套的问题:
#!/bin/bash
name="zs"
age=10
echo '$name$age'
echo '"$name$age"'
echo "'$name$age'"
echo "`date`"
echo "`$name`"
echo "$name........$age"
echo "${name}......${age}"
echo "$name...."天气很热"....$age"
echo "$name....\"天气很热\"....$age"
echo `$name`
echo $name$age
输出结果:
$name$age ---》 单引号里面取不出变量值
"$name$age" ---》单引号嵌套双引号的结果
'zs10' ---》双引号嵌套单引号 就ok了
2021年 06月 30日 星期三 18:41:07 CST ---》双引号嵌套`也 ok
03.sh:行8: name: 未找到命令
zs........10
zs......10
zs....天气很热....10 ---》我们期望的结果zs...."天气很热"....10
zs...."天气很热"....10 ---》转义参见上面
03.sh:行8: zs: 未找到命令 ---》说明`这里放命令`,即`能取到变量值`,会报错,也不是期望的
zs10 ----》不加引号也能取出来变量值
只读变量的定义:---》Java中的常量
[root@hadoop101 shell]# readonly name="zs"
[root@hadoop101 shell]# echo $name
zs
[root@hadoop101 shell]# name="zsaaaaa"
-bash: name: 只读变量
撤销变量:这个动作,一般也不做!!!!
[root@hadoop101 shell]# unset name:只读变量不能撤销
-bash: unset: name: 无法反设定: 只读 variable
[root@hadoop101 shell]# echo $score
true
[root@hadoop101 shell]# unset score
字符串其他操作:了解
1.echo ${#string} 获取长度
2.提取子串:${string:1:1}
3.查找子串
string="i am a boy"
echo `expr index "$string" am` # 输出是: 3
4.Shell传参【非常非常非常重要】
前5个必须掌握
1.sh脚本后面跟参数 ---》类似Java中的方法调用,传实参
通过$n获取参数值 : 0~无穷大,0-9 直接这么写 $0,....$9, 10及以上 ${10}....
2.拿到参数的个数:$#
3.最后命令是否执行成功:$? --》可以根据这个值,结合流程控制做进一步处理!!
4.以一个单字符串显示所有向脚本传递的参数:$*
5.与`$*`相同,但是使用时加引号,并在引号中返回每个参数:$@
6.脚本运行的当前进程ID号:$$
7.后台运行的最后一个进程的ID号:$!
实例:04.sh
#!/bin/bash
# 获取参数值
echo $0
echo $1
echo $2
echo $3
# 获取参数个数
echo $#
# 获取参数值
echo $*
echo $@
#获取上面命令是否执行正确,正确返回0
echo $?
[root@hadoop101 shell]# sh 04.sh 10 20 30 40
04.sh ---> $0脚本名称
10
20
30
4 ----> $? 个数
10 20 30 40
10 20 30 40
0
echo $*和echo $@ 的区别 05.sh
#!/bin/bash
echo "-- $* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- $@ 演示 ---"
for i in "$@"; do
echo $i
done
结果输出:
[root@hadoop101 shell]# sh 05.sh 10 20 30 40
-- 10 20 30 40 演示 ---
10 20 30 40
-- 10 20 30 40 演示 ---
10
20
30
40
5.read读取控制台输入
类似java之Scanner用法
-p 后面跟提示信息,即在输入前打印提示信息
-t 后面跟秒数,定义输入字符的等待时间,若过了这个时间,依然没有输入的话,即变量没赋值成功
06.sh
#!/bin/bash
read -p "输入参数1:" name
read -t 30 -p "please enter your age in 30 seconds: " age
echo $name$age
6.算术运算符
07.sh --->忘记吧!!!
#!/bin/bash
result=`expr 1 + 1`
a=`expr 1 \* 2`
echo $result
echo $a
注意:
1.表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
2.完整的表达式要被 ` 包含,注意不是单引号,在 Esc 键下边。
3.乘法需要注意,特殊,需要转义: \*
上面使用expr比较难受,我们可以使用如下方式进行算术运算
c=$((a+b)) ---》了解
d=$[a+b] --》建议使用这种方式 ,好记
08.sh
#!/bin/bash
c=$(($1+$2))
d=$[$1+$2]
echo $c
echo $d
[root@hadoop101 shell]# sh 08.sh 10 20
30
30
7.流程控制
java:
循环【while、do-while、for】
分支【if【单重、双重、多重、嵌套】、switch】
switch() --> byte/short/char/int/boolean 字符串 枚举
枚举怎么定义?enum TrafficLights {RED,YELLOW,BLUE}
分支:
if分支【单重、双重、多重、嵌套】
语法:多行写法
if condition
then
command1
command2
...
commandN
fi
语法:一行写法,注意then前面的分号
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
双重语法
if condition1
then
command1
else
fi
多重语法:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
嵌套if
case分支
循环:
for循环
while循环
do-while
break、continue
需求1:09.sh,控制台输入一个数字,若>18,输出成年人;否则小屁孩 if -else
加上,若输入的参数个数不是1,给一个提示,且退出!!
#!/bin/bash
# 参数校验
if [ $# != 1 ]
then
echo "参数个数不对,请输入一个参数"
exit
fi
echo "输入的年龄:$1"
if [ $1 -gt 18 ]
then
echo "成年了"
else
ehco "小屁孩"
fi
注意点:
1.语法不要错
2.if的中括号,前后要有空格
3.获取参数个数要正确
4.退出exit,在校验不通过的时候,可以使用exit 1
5.比较运算符
6.若是从xx.sh中接收的参数,if [ $# -ne 1 ] 可能更好一点【一般使用这种】;若
在脚本中获取变量值,进行比较,$[num1] -eq $[num2]
7.$[ $1 > 18 ] 这种比较的结果是0或1,而不是true和false
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
需求2:10.sh,控制台输入一个数字,定义几个范围,[0,18],(18,40],[40,),给出对应的提示 多重if
#!/bin/bash
read -p "输入年龄:" age
if [ $age -gt 40 ]
then
echo "大小孩"
#elif [ $age -gt 18 -a $age -le 40 ]
elif [ $age -gt 18 ] && [ $age -le 40 ]
then
echo "aaaa"
else
echo "bbbb"
fi
注意:
在逻辑运算符拼接的时候,可以使用两种方式,注意区别
[ $age -gt 18 -a $age -le 40 ]
[ $age -gt 18 ] && [ $age -le 40 ]
需求3:11.sh,输入两门课的成绩,math,english, math>=95,且english>=90,给个提示
if-else,条件使用逻辑运算符拼接 ----》 略
还需要掌握的运算符
1.字符串比较
==
!=
2.文件运算符 -d -e -f -w -r -x
case分支
case 变量 in
值1)
语句
;;
值2)
语句
;;
*)
语句
esac
一般用于写启动脚本,status start stop,比如zk、hadoop、hbase、tomcat
搞一个防火墙相关的脚本 12.sh
例子:
#!/bin/bash
sta=$1
#加入判断参数个数合法性校验
if [ $# -ne 1 ]
then
echo "arguments is valid or arguments nums is not correct!!!"
exit
fi
case $sta in
"start")
systemctl start firewalld
;;
"stop")
systemctl stop firewalld
;;
"status")
echo "status"
systemctl status firewalld
;;
*)
echo "输入的命令参数不对......"
;;
esac
试下:切换到/opt/shell目录,执行01.sh /opt/shells/01.sh
写一个tomcat 的启停脚本
安装:解压即可【前提是需要安装JDK,因为Tomcat就是用java开发的】
1.启动:startup.sh
启动完之后,可以在网页中进行验证:ip地址或者主机名称:8080
2.关闭: shutdown.sh
试下:防火墙开启能否打开!!!
循环
1.for循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
2.while循环
while condition
do
command
done
需求1:五台机器,分别是node01 .... node05,分别打印出hostname 13.sh
#!/bin/bash
for host in node01 node02 node03
do
echo "connect to $host"
done
for host in `cat /etc/hosts`
do
echo "connect to $host"
done
需求2:列出/etc的文件名称【过滤出某几个字母开头】 14.sh
#!/bin/bash
for file in `ls /etc | grep conf`
do
echo "fileName is: $file"
done
需求3:1-100的和 15.sh
#在循环中,如何更新循环变量 for(int i=1;i<=100;i++)
for((i=0;i<=100;i++))
#!/bin/bash
sum=0
for((i=0;i<=100;i++))
do
sum=$[$sum + $i]
done
echo "1-100的和为:$sum"
需求4:使用while,输出1-5的偶数 16.sh
#!/bin/bash
i=1
while(( $i<=5 ))
do
# echo $i
if [ $[$i%2] -eq 0 ] 正确用法
#if [ $i%2 -eq 0 ] # 错误的用法
then
echo $i
fi
#let "i++" 等效于下面的写法
i=$[$i + 1]
done
练习:搞定9*9乘法表
#!/bin/bash
for((i=0;i<=5;i++))
do
echo -ne "$i\t"
done
-n:默认echo是换行的,让其不换行显示
-e:让其能够解析到我们的转义字符,比如\t、\n .....
1.while的基本使用
2.完成tomcat的启停脚本
3.预习shell剩下,以及shell工具 cut、set、awk、sort、wc --》这几个基本的,也蛮重要的!
shell编程笔记
最新推荐文章于 2022-04-26 03:55:29 发布