快速有效的学习,思想核心是“以建立知识体系为核心”,具体方法是“守破离”。确保老师课堂上做的操作,反复练习直到熟练。
学习主题:shell编程
(类似与javascript:解释器是:浏览器)
应用:
1、写一些shell脚本来调用大数据的程序
2、可以看懂大数据平台各个分布式节点运行的机制
知识准备:解释器:bash 。bash :命令行类型的shell。 shell :计算机和用户的交互接口。
包括用户交互输入和文本文件输入;
运行任何一个脚本都是启动一个新的bash去运行;
脚本的本质:#! /bin/bash #! /usr/bin/python
运行方式:
source 和 . 是在父bash中执行
bash 和 ./ 是在子bash执行
文本流和重定向
重定向:不是命令
1.输出重定向(>&):覆盖重定向和追加重定向
2.输入重定向(<<<或者<<):
程序自身都有I/O
0:标准输入
1:标准输出
2:错误输出
控制程序I/O位置
一切皆文件
/proc/$$/fd
#客–>服 在服务端开启一个虚拟终端
#任何一个命令都有一个输入输出方式,重定向就是认为干预0,1,2的输出位置
输出重定向
ls 1> aaa #这是就是标准输出重定向到文件,会覆盖文件原内容
ls / /tmp 1>>bbb #追加输出到文件
##从左向右依次绑定
##标准输出和错误输出重定向到一个文件中,错误输出在前面,跟重定向顺序无关
##2重定向到1中,1重定向到文件中
#ls / /aa 1>>ls03.out 2>>ls03.out
写法2:
#ls / /as 1>ls05.out 2>&1
写法3,可省略文件描述符:
#ls / /as >& ls06.out
#ls / /as &> ls06.out
左边不能包含空格
执行过程:
先检索这两个目录是否存在,如果aa不存在,先执行错误输出,再执行/,追加到一个文件中
-
输出 重定向中 ls 命令后可多个目录,输出顺序是怎样的呢
按照目录的深度,由内到外输出
在同级目录下是按照字典序输出
-
输入重定向:对换行符敏感
<<< 表示从一个字符串读数据
<< 指定一个结束符<<E,把第一个换行符前的内容输入进来
< 从一个文件进行输入
[root@bd002 out]# read ab <<<"hello linux" [root@bd002 out]# echo $ab hello linux 法2: [root@bd002 out]# read aaa <<BB > asd > ds > qw > ew > BB [root@bd002 out]# echo $aaa asd
应用:访问百度
[root@bd002 fd]# exec 8<> /dev/tcp/www.baidu.com/80
[root@bd002 fd]# echo -e "GET / HTTP/1.0
" 1>&8
[root@bd002 fd]# cat 0<&8
HTTP/1.1 200 OK
Date: Thu, 06 Jun 2019 03:39:23 GMT
Content-Type: text/html
Content-Length: 14615
Last-Modified: Tue, 04 Jun 2019 06:04:12 GMT
Connection: Close
....
exec命令:命令代替shell程序,命令退出,shell 退出;比如 exec ls
虽然exec和source都是在父进程中直接执行,但exec这个与source有很大的区别,source是执行shell脚本,而且执行后会返回以前的shell。而exec的执行不会返回以前的shell了,而是直接把以前登陆shell作为一个程序看待,在其上经行复制。
exec 文件重定向,可以将文件的重定向就看为是shell程序的文件重定向 比如 exec 5</dev/null;exec 5<&-
exec命令 | 作用 |
---|---|
exec ls | 在shell中执行ls,ls结束后不返回原来的shell中了 |
exec <file | 将file中的内容作为exec的标准输入 |
exec >file | 将file中的内容作为标准写出 |
exec 3<file | 将file读入到fd3中 |
sort <&3 | fd3中读入的内容被分类 |
exec 4>file | 将写入fd4中的内容写入file中 |
ls >&4 | ls将不会有显示,直接写入fd4中了,即上面的file中 |
exec 5<&4 | 创建fd4的拷贝fd5 |
exec 3<&- | 关闭fd3 |
学习目标
-
掌握shell的基本语法
-
变量
-
本地变量:作用在当前shellscript中,shell脚本在运行时启动一个子bash来解释的
-
环境变量:作用在当前的shell(bash)及其子shell(bash),
export 名字=值,作用域:当前的shell和其子shell。
-
局部变量: local var_name =值,作用域:当前代码段。
-
特殊变量 :bash内置的用来保存某些特殊数据的变量。(也叫系统变量)
本地变量:只属于某一个shellscript的变量。
KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲,?,位置变量:$1,$2,$3…
命令 含义 $? 上一个命令的执行状态返回值 $# 传递到脚本的参数个数 $* 传递到脚本的参数,与位置变量不同,此选项参数可超过9个 $$ 脚本运行时当前进程的ID号,常用作临时变量的后缀,如 haison.$$ $! 后台运行的(&)最后一个进程的ID号 $@ 与$#相同,使用时加引号,并在引号中返回参数个数 $- 上一个命令的最后一个参数 程序有两类返回值: 1、 执行结果 :标准,错误 :标准输出,错误输出 2、 执行状态,$? : 0:表示正确,1-255:错误 输出重定向: >覆盖重定向 >> 追加重定向 2> 错误覆盖重定向 2>>错误追加重定向 &> 全部重定向 &>> 全部信息追加重定向 撤销变量: unset 变量名
-
-
条件判读
- if 。。elif。。。 else
- 逻辑运算来做条件判读 : && 或者 ||
- 条件表达式:数值比较,字符串,文件,权限。命令
条件判断: 条件表达式: 1、 [ expression ] 2、 test expression 3、 任何一个命令都可以作为条件表达式 整数比较: -eq : 比如:[ $A –eq $B ] -ne , -gt ,-lt,-ge,-le 命令的逻辑关系: 在linux 中 命令执行状态:0 为真,其他为假 逻辑与: && 第一个条件为假时,第二条件不用再判断,最终结果已经有; 第一个条件为真时,第二条件必须得判断; 逻辑或: || 逻辑非: ! 命令执行的状态 的逻辑关系 1、如果用户user6不存在则添加用户6 ! id user6 && useradd user6 Id user6 || useradd user6 2、如果用户不存在,添加用户并显示添加成功,否则显示其已存在 3、如果/etc/inittab文件的行数大于50,就显示好大的文件; 备注: passwd默认是要用终端作为标准输入,加上--stdin表示可以用任意文件做标准输入 于是这里用管道作为标准输入 条件判断,控制结构: If 条件 ;then 语句 elif 条件 ; then 语句 else 语句 fi -a : 逻辑与,并且 : if [ $# -gt 1 –a $# -lt 3 –o $# -eq 2 ] ; then -o :或者 比如: bash -n shell文件 :检查文件是否有语法错误。 bash –x shell 文件 :debug 执行文件 Shell 中如何算术运算 1、 let 算术运算表达式 let C=$A + $B 2、$[算术表达式] C = $[$A+$B] 3、$((算术表达式)) C=$(($A+$B)) 3、 expr 算术表达式 ,注意:表达式中各操作数及运算符之间要有空格。而且要使用命令引用 C=`expr $A + $B` 练习:给定一个用户,获取其密码警告期限,然后判断用户密码使用期限是否已经小于警告期限,如果小于,则是显示“WARN” ,否则显示密码还有多少天到期。 提示:date +%s :今天的秒数 Cat /etc/shadow 密码时间。 exit : 退出脚本 退出脚本可以指定脚本执行的状态:exit 0 。
-
循环
- for循环
- while循环
-
了解函数
-
了解case语句
循环:进入条件,退出条件 for 变量 in 列表 ; do 语句 done 比如: for I in 1 2 3 4 5 ;do 语句 done、 如何生成列表: 1、{1..100} 2、seq [起始数] [跨度数] 结束数 3、ls /etc 文件列表 While 循环 格式一 while 条件;do 语句 [break] done 格式二 死循环 while true do 语句 done 格式三 死循环 while : do 语句 done 格式四 死循环 while [ 1 ] do 语句 done 格式五 死循环 while [ 0 ] do 语句 done echo –n $RANDOM 函数: Function 名字() case 语句 case 变量 in value1) 语句 ;; value2) 语句 ;; *) 语句 ;; esac
-
练习
-
写一个shell脚本,功能如下:
(1)创建目录/tmp/ scripts
(2)切换工作目录至此目录中
(3)复制/etc/pam.d 目录至当前目录,并重命名为test
(4)将当前目录的test 及其里面的文件和子目录的属主改为hadoop
(5)将test 及其子目录中的文件的其它用户的权限改为没有任何权限
#! /bin/bash mkdir -v /tmp/scripts cd /tmp/scripts cp -r /etc/pam.d ./test chown -R hadoop ./test chmod -R o=--- ./test
-
写一个tomcat的服务脚本,使tomcat能自动随机启动。
- 先在/etc/init.d/ 创建tomcat脚本,并保证脚本正确。
- 修改tomcat的catalina.sh 的源码。让tomcat启动的时候把PID打印出来
- chkconfig tomcat on 设置tomcat随机自动启动
#!/bin/bash
#
# tomcat
#
# chkconfig: 2345 65 35
#description:the description of the shell
. /etc/rc.d/init.d/functions
tomcat_home="/usr/local/tomcat8"
#根据PID判断tomcat是否已经启动
pid_file=/tmp/tomcat.pid
#判断tomcat是否启动
tomcat_status(){
if [ -f $pid_file ];then #tomcat的进程ID保存到pid_file中,判断该文件存在
PID=`cat $pid_file`
if [ ! -s $PID ];then # 判断本地变量PID是否不为空
checkpid $PID #检查当前tomcat进程是否正在运行
return $?
fi
fi
return 1
}
#启动tomcat
tomcat_start(){
#判断pid文件是否存在
if [ ! -f $pid_file ];then
touch $pid_file
fi
#启动tomcat
tomcat_status
if [ $? -eq 0 ];then
echo "tomcat已经启动,不需要再次启动"
return 0
fi
#执行tomcat的startup.sh
if [ -x "$tomcat_home/bin/startup.sh" ];then
$tomcat_home/bin/startup.sh | grep "^Tomcat started" | cut -d"=" -f2 >$pid_file
fi
}
#停止tomcat
tomcat_stop(){
tomcat_status
if [ $? -eq 0 ];then
if [ -x "$tomcat_home/bin/shutdown.sh" ];then
$tomcat_home/bin/shutdown.sh &>/dev/null
return $?
else
echo "该用户没有执行的权限,请检查"
fi
else
echo "tomcat没有启动,不需要停止"
return 0
fi
}
#根据参数判断要执行的操作
case $1 in
"start")
#启动
tomcat_start
if [ $? -eq 0 ];then
tomcat_status && echo "tomcat已经启动成功"
else
echo "tomcat启动出错,请检查"
fi
;;
"stop")
#停止
tomcat_stop
if [ $? -eq 0 ];then
echo "tomcat已经停止..."
fi
;;
"restart")
#重启
tomcat_stop
sleep 1
tomcat_start
;;
"status")
#查看tomcat状态
tomcat_status
if [ $? -eq 0 ];then
echo "tomcat正在运行...."
else
echo "tomcat没有启动"
fi
;;
*)
echo "传入参数错误"
echo "参数只能是:tomcat {start|stop|restart|status} 其中一个"
exit 2
;;
esac