shell编程笔记

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 --》这几个基本的,也蛮重要的!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值