一、Shell简介
Shell的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive)。通俗易懂的来说,是一个环境提供了对Linux系统的接口,可以系统输入一些东西,系统根据你输入的东西,执行程序,并显示程序的输出。
Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译。
那什么是脚本呢?
脚本简单来说就是的集合,抑或理解成一个文件中编辑了很多命令,如果一行一行写,只能一行一行去执行,而把很多命令封装到一个文件中,可以直接执行这些命令。
为什么需要脚本呢?
举个例子,比如我们所熟悉的hadoop、hive、hbase、zookeeper生态圈,以往我们可能一个服务一个服务去启动,如下图,而现在我们可以通过shell写一个脚本,把所有的启动命令行放到脚本里,这样可以实现一次性启动所有服务。
#未学习shell之前
#查看MySQL启动状态
systemctl status mysql;
#启动hadoop
start-all.sh
stop-all.sh
#启动hive
#生成日志文件
nohup --service metahouse>hive.log 2>&1 &
nohup --service hiveserver>/dev/null 2>&1 &
#客户端启动
beeline -u jdbc:hive2://192.168.199.130:10000
#启动zeepline,在bin目录下启动
#首先进入zeepline下的bin 目录
cd /opt/software/hadoop/zeepline082/bin/
./zeepline-dameon.sh
!!注意点:一定要先启动zookeeper,再启动hbase
#启动zookeeper
zkServer.sh start
zkServer.sh stop
#启动hbase
start-hbase.sh
stop-hbase.sh
#进入hbase
hbase shell
二、执行脚本
1.第一个shell脚本
//在虚拟机根目录下新建一个shell目录,所涉及文件都放在该目录下
[root@single shell]# vi demo.sh
// 此时我们发现demo.sh 没有执行权限,则需要添加权限
u+x:对当前这个文件的用户授予执行权限
[root@single shell]# chmod u+x demo.sh
// 调用脚本语句
[root@single shell]# ./demo.sh
// 执行结果如下
//:W只保存不退出
shell 脚本的开头必须是#!/bin/bash
注意:尽量不要在两个窗口打开同一个文件,会出现一个缓存文件,swap文件,为了数据同步,每一个打开文件的地方都能可以对文件进行单独处理,而不是对同一个文件处理,因此会在第二次打开文件的地方建一个临时文件,瞬时同步,相当于建立了一个拷贝。
所有我们尽量对文件都是采取:w只保存不退出,来回两个窗口之间切换。
2.注释
单行注释 #
多行注释 :<<! !
3.变量的创建和使用
变量:数字、字母、下划线,一般字母大写
值可以是一个数字、文本、文件名、设备或任何类型的数据,不可以是指针。
变量名和美元符号之间不能有空格
shell可以创建,分配和删除变量
#创建
NAME="henrry"
AGE=18
#使用
echo "$NAME,$AGE"
#取消(删除)
echo "please enter your name => "
read NAME
echo "your name is $NAME"
unset NAME
echo "your name is $NAME"
#很明显第二个没有出现姓名
#变量被删除后不能再次使用。unset 命令不能删除只读变量
4、常量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
readonly AGE=18
echo "age:$AGE"
AGE=22
三、变量的分类
局部变量:当前实例有效
环境变量:跨实例访问 如何JAVA_HOME HADOOP_HOME
临时变量
查看当前系统的所有环境变量:export -p
export AENV
export -p 列出所有环境变量
export -n VAR 删除环境变量VAR
export VAR 添加环境变量VAR
$$ 当前shell进程编号
$0 当前脚本的文件名
$n 脚本参数 如:./demo.sh henrry 18 ,则脚本中$1的值就是henrry,$2为18 (常用)
$# 脚本参数的数量 (常用)
$* 脚本参数的完整集合 (常用)
$@ 脚本参数的独立集合
$? 上一条命令的执行结果
$! 上一条后台命令的进程号
注意:$* 与 $@的不同
echo $* 强调的是整体
echo $@ 强调的个体
不加""的时候,结果一样,加""时,$*强调整体,$@强调个体
四、数组
标准变量:保持一个类型值一个值
数组:支持不同类型的变量,可以同一时间容纳多个值
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n)
例如:存放了不同类型的值
NAME=(aa 18 true)
NAME[0]="henrry"
NAME[1]="pola"
NAME[2]="ariel"
#使用
echo $NAME 首元素
echo ${NAME[0]} 第一个元素
echo ${Name[1]}
echo ${Name[2]}
echo ${NAME[*]} 所有元素
echo ${NAME@}
echo ${#NAME[*]} 数组长度
使用 @ 符号可以获取数组中的所有元素
array_Name=(10,2,4,6)
echo ${array_Name[@]}
获取数组中某个值
//标准创建方式
NAME[0]="zs"
NAME[1]="ls"
NAME[2]="ww"
NAME[3]="zl"
NAME[4]="zs"
echo ${NAME[2]}
获取数组长度,在{}内的变量名之前加上#
NAME[0]="zs"
NAME[1]="ls"
NAME[2]="ww"
NAME[3]="zl"
NAME[4]="zs"
#echo ${NAME[2]}
#这两张方式都能获取数组长度
echo ${#NAME[*]}
#echo ${NAME[@]}
遍历数组的小案例
for var in aa bb cc
do
echo $var
done
五、运算符
1、算术运算符
#第一种方式
let "var=2+3"
echo $var
#第二种方式
var=$((2+3))
echo $var
#第三种方式
#尤其要注意空格
val=`expr 2 + 2`
echo "$val"
这三种方式最后结果都一样
测试各种算术运算符
var=`expr 2 + 3`
echo $var
var=`expr 2 - 3`
echo $var
var=`expr 2 \* 3`
echo $var
var=`expr 2 / 3`
echo $var
var=`expr 2 % 3`
echo $var
var
测试 == 和!=
if [ $1 == "henrry" ]
then
echo "is henrry"
else
echo "is not henrry"
fi
if [ $1 != "henrry" ]
then
echo "is not henrry"
fi
2、关系运算符
-eq 检测两个数是否相等,相等返回 true [ $a -eq $b ] 返回 false
-ne 检测两个数是否不相等,不相等返回 true [ $a -ne $b ] 返回 true
-gt 左边的数大于右边的,则返回 true [ $a -gt $b ] 返回 false
-lt 左边的数小于右边的,则返回 true [ $a -lt $b ] 返回 true
-ge 左边的数大于等于右边的,则返回 true [ $a -ge $b ] 返回 false
-le 左边的数小于等于右边的,则返回 true [ $a -le $b ] 返回 true
案例:
AGE=$1
if [ $AGE -ge 18 ]
then
echo "成年"
else
echo "未成年"
fi
执行脚本,输出结果如下所示:
3、字符串运算符
#二元:== !=
=~ 正则匹配
配合[[ $var =~ PATTERN ]] 使用
正则匹配
^ 开始
$ 结束
. 一个任意字符
[] 指定范围 [abc] [a-z] [^a-b1-9]
\< 单词开始
\> 单词结束
\b 单词开始或结束
\B 非单词开始或结束
? {0,1}
+ {1,}
* {0,1}
{n,m} 最少n,最多m
{n,} 最少n次
{,m} 最多m次
{f} 固定f次
\ 转义符
| 或
if [ $1 == "henrry" ]
then
echo "is henrry"
else
echo "is not henrry"
fi
#一元
if [[ -z $1 ]]
then
echo "is empty"
else
echo "is not empty"
fi
4、布尔运算符
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
5、文件测试运算符
-e -d -f -r -w -x -s
-e:检测目录是否存在
-d: 检测是否是目录
-f:检测是否是文件
-r:检测文件是否可读
-w:检测文件是否能可写
-x:检测文件是否可执行
-s:检测文件是否为空
6、特殊表达式
<=> $() #命令替换符号,兼容性更好、
OUTPUT=start-all.sh #先执行start命令,执行完把结果赋值给OUTPUT,默认有线程等待,延时加载
小案例:打印10之前的数字
I=0
while [ $I -le 10 ]
do
echo $I
((I++))
done