shell之 概念
Shell是用户与Linux操作系统沟通的桥梁
Linux的Shell种类众多,这里我们学习的是bash,也就是Bourne Again Shell
由于易用和免费,Bash在日常工作中被广泛使用
Bash是大多数Linux系统默认的Shell。
文件名后缀通常是.sh
#!/bin/bash
#这里是注释
在一般情况下,人们并不区分 Bourne Shell和Bourne Again Shell,所以,在这里,我们可以看到#!/bin/bash,它同样也可以改为#!/bin/sh。
shell之 变量概念
0 变量不需要声明,初始化不需要指定类型
变量命名
1:不能使用程序中的关键字(保留字)
2:只能使用数字,字母和下划线,且不能以数字开头
3:建议命令要通俗易懂
1 变量使用两种方式
$变量名
${变量名}
例如:echo $JAVA_HOME
或者echo ${JAVA_HOME}
两种方式的区别:
如果变量后紧跟着别的字符,请用${} eg: ${JAVA_HOME}isthepath
shell之 变量分类
本地变量
只对当前shell进程有效的,对当前进程的子进程和其它shell进程无效。
定义:VAR_NAME=VALUE
变量引用:${VAR_NAME}
取消变量:unset VAR_NAME
环境变量
自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效
关键词: export
定义:export VAR_NAME=VALUE
对所有shell进程都有效需要配置到配置文件中
vi /etc/profile
source /etc/profile
局部变量
函数调用结束,变量就会消失
对shell脚本中某代码片段有效
关键词 local
定义:local VAR_NAME=VALUE
位置变量
$1,$2,.....${10}....
test.sh 3 89
$0:脚本自身
$1:脚本的第一个参数
$2:脚本的第二个参数
特殊变量
$?:接收上一条命令的返回状态码
$#:参数个数
$*:或者$@:所有的参数
$$:获取当前shell的进程号(PID)(可以实现脚本自杀) kill -9 pid是他杀 kill $$是自杀
shell之 脚本执行的三种方式
1 相对路径下执行
切换到你的shell文件所在的目录下来, 通过 ./you.sh来执行
因为你的shll文件目录未必就在PATH环境变量中,因此需要切换到你的shell文件所在目录后
显示声明在当前目录下 ./来执行你的shell文件
2 绝对路径下执行: /data/shell/hello.sh
3 直接使用bash 或sh 来执行bash shell脚本
是以方法三的方式来执行,那么,可以不必事先设定shell的执行权限,甚至都不用写shell文件中的第一行(指定bash路径)。因为方法三是将hello.sh作为参数传给sh(bash)命令来执行的。这时不是hello.sh自己来执行,而是被人家调用执行,所以不要执行权限。那么不用指定bash路径自然也好理解了
cd /data/shell
bash hello.sh
或者:
cd /data/shell
sh hello.sh
shell之 三种引号
''单引号不解析变量, 里面是啥就打印啥
""双引号会解析变量, eg echo "$name" 就会打印 zm出来
``反引号是执行并引用一个命令的执行结果,类似于$(...)
eg `$JAVA_HOME` : 1 先将$JAVA_HOME解析出来 2 将$JAVA_HOME解析出来的字符串作为命令来执行
eg `echo ls` 将 echo ls的东西作为命令来执行,最终打印出当前目录下所有的文件夹
shell之 条件测试:
bash条件测试
命令执行成功与否即为条件测试
两种方式:
test EXPR
[ EXPR ]:注意中括号和表达式之间的空格
整型测试:
-gt:大于:例如[ $num1 -gt $num2 ] gt = greater
-lt:小于 lt = lowter
-ge:大于等于 ge = great equal
-le:小于等于 le = lower equal
-eq:等于 eq = equal
-nq:不等于 nq = not equal
字符串测试: ------> 是按照字典顺序比较的 如果是数字来比较 那么应该用上面写法
>:大于[ "$str1" \> "$str2" ] 注意测试符号左右的空格 \是转义符
<:小于
=
!=
shell之 算术运算
shell是弱类型 因此1+2会被理解为字符串
let varNamer=算术表达式 --->最常用
varName=$[算术表达式]
varName=$((算术表达式))
varName=`expr $num1 + $num2`
shell之 for循环
通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环
格式1
for ((i=0;i<10;i++))
do
...
done
格式2
for i in 0 1 2 3 4 5 6 7 8 9
do
...
done
格式三
for i in {0..9}
do
...
done
shell之 while/until循环
适用于循环次数未知,或不便用for直接生成较大的列表时
格式:
while 测试条件;do
循环体
done
如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。
until循环的格式和while循环的格式一致,但是和while循环的意思相反,如果测试条件为假,则进入循环,退出条件为,测试条件为真
for 和 while 类似, 都是 do 循环体 done 仅仅是头部分写法不一样 for ((...)) while [ 1 -eq 2 ]
shell之 if
单分支
if 测试条件;then
选择分支
fi
双分支
if 测试条件; then
选择分支1
else
选择分支2
fi
多分支
if 条件1; then
分支1
elif 条件2; then
分支2
elif 条件3; then
分支3
...
else
分支n
fi
shell之 case
有多个测试条件时,case语句会使得语法结构更清晰
格式: case 变量引用 in
PATTERN1)
分支1
;;
PATTERN2)
分支2
;;
...
*)
分支n
;;
esac
PATTERN :类同于文件名通配机制,但支持使用|表示或者
a|b:a或者b
*:匹配任意长度的任意字符
?:匹配任意单个字符
[a-z]:指定范围内的任意单个字符
eg:
case $1 in
1)
echo "1"
;;
2)
echo "2"
;;
*) *在linux统配所有,如果上面的流程都没走到,那么$1的数据必然会被*统配匹配到 从而输出none
echo "none"
;;
shell之 自定义函数:
function 函数名(){
....
}
引用自定义函数文件时,使用source func.sh
有利于代码的重用性
eg:
[root@bogon ~]# cat hello.sh
#!/bin/sh
#
function hello(){
echo "hello world"
}
[root@bogon ~]# cat test.sh
#!/bin/sh
#
source /root/hello.sh ----> 引用文件
hello ----> 执行引用文件内的函数
[root@bogon ~]# ./test.sh
hello world
shell之 date
显示当前时间
格式化输出 +%Y-%m-%d
linux时间-->人类时间
格式%s表示自1970-01-01 00:00:00以来的秒数
指定时间输出 --date='2009-01-01 11:11:11' 人类时间-->linux时间
指定时间输出 --date='3 days ago'
date +%Y-%m-%d --date='3 days ago' 今天的3天前的日子 用 y-m-d格式输出
date +%s
date --date='2015-12-11' +%s
这样可以比较这两者的差值