Shell脚本
简介
Java编程使用Java语言编程实现用户的业务逻辑。Shell编程把用户需要在命令行下面(Linux命令行)执行的命令放到一个文件夹当中,然后批量执行,用户使用起来就会很方便。将大量的命令放到一个文件当中,这个文件称之为脚本(将一批命令集合起来成脚本),这个过程称为shell编程。
变量
变量不需要声明(在java类中定义的变量需要声明:int、string型、布尔型),初始化不需要指定类型 (bash里面都是“弱”类型,默认情况下一个变量保存一个串)
(1)变量命名
1:不能使用程序中的关键字(保留字)
2:只能使用字母、下划线和数字,且不能以数字开头
3:建议命令要通俗易懂
显示变量值使用echo命令(往控制台输出命令) ,加上
变量名,也可以使用
{变量名}
echo $JAVA_HOME
echo ${JAVA_HOME}
可以简单理解
echo
JAVAHOME是echo
{JAVA_HOME}的简写,执行的结果都一样,echo ${JAVA_HOME}(建议这样写,清晰)
(2)环境变量
自定义的环境变量(在当前命令行中配置)对当前shell进程及其子shell进程有效,对其它的shell进程无效
定义:export VAR_NAME=VALUE
对所有shell进程都有效需要配置到配置文件中
vi /etc/profile
source /etc/profile
定义export crxy=/usr/local(环境变量路径)
(3)局部变量
函数调用结束,变量就会消失
对shell脚本中某代码片段有效
定义:local VAR_NAME=VALUE
source /etc/profile修改完环境变量以后,要重新加载这个文件,就可以获取到刚刚定义的变量
(4)位置变量
$1,$2,.....${10}....
test.sh 3 89
$0:脚本自身
$1:脚本的第一个参数(获得数字3)
$2:脚本的第二个参数(获得数字89)
test.sh(脚本文件) start(位置变量,用于传递参数,在脚本里面可以获取得到的,启动脚本文件)
(5)特殊变量
$?:接收上一条命令的返回状态码
$#:获取后面参数个数(作用:执行脚本时,后面不传递参数少或不够,会反馈提醒)
$*:或者$@:所有的参数
$$:获取当前shell的进程号(PID)(可以实现脚本自杀)
单引号、双引号、反引号(esc下面的键)
''单引号不解析变量(将变量直接输出)
""双引号会解析变量
``反引号是执行并引用一个命令的执行结果,类似于$(...)(例如把crxy=haha,将haha当做是一个命令,如果是路径,也将会当成是文件目录)
for
For
格式1
for ((i=0;i<10;i++))
do(表示开始)
...(业务逻辑)
done(表示结束)
格式2
for i in 0 1 2 4 5 8 9
do
...
done
拷贝有执行权限的文件后的文件已有执行权限,不用在加执行权限
条件测试
bash条件测试
命令执行成功与否即为条件测试
test EXPR(表达式expression)
[ EXPR ]:注意中括号和表达式之间的空格
整型测试:
-gt:(greater than)大于:例如[ $num1 -gt $num2 ]或者test $num1 -gt $num2
-lt:(less than)小于
-ge:(greater than or equal to)大于等于
-le:(less than or equal to)小于等于
-eq:(equal to)等于
-ne:(not equal to)不等于
字符串测试:
> 大于[ "$str1" \> "$str2" ] 注意测试符号左右的空格(字典顺序,>需加\转义符号,$是取变量的值)
< 小于
=
!=
while/until循环
适用于循环次数未知,或不便用for直接生成较大的列表时
格式:
while 测试条件;do
循环体
done
如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。
until循环的格式和while循环的格式一致,但是和while循环的意思相反,如果测试条件为假,则进入循环,退出条件为,测试条件为真
#!/bin/bash
while [ 10 -gt 2 ]
do
echo 'true'
done
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(结束)
单分支
#!/bin/bash
if [ $1 -gt 5 ]
then
echo $1
fi
#------
if [ $1 -gt 5 ]
then
echo $1
else
echo "no"
fi
#!/bin/bash
#多分支
if [ $1 -eq 1 ]
then
echo "one"
elif [ $1 -eq 2 ]
then
echo "two"
elif [ $1 -eq 3 ]
then
echo "three"
else
echo "none"
fi
判断一个变量为空
#!/bin/sh
#-n为非空字符串 -z为空字符串
para1=
if [ ! -n "$para1" ]; then
echo "IS NULL"
else
echo "NOT NULL"
fi
#或者if [ ! $para1 ]; then
#都输出 "IS NULL"
#或者使用test
#!/bin/sh
dmin=
if test -z "$dmin"
then
echo "dmin is not set!"
else
echo "dmin is set !"
fi
#"dmin is not set!"
case判断
有多个测试条件时,case语句会使得语法结构更清晰
格式: case 变量引用 in
PATTERN1)
分支1
;;(符合这个case就会退出循环如同Java里面还有个break)
PATTERN2)
分支2
;;
...
*)
分支n
;;
esac(case倒着写表退出)
PATTERN :类同于文件名通配机制,但支持使用|表示或者
a|b:a或者b
*:匹配任意长度的任意字符
?:匹配任意单个字符
[a-z]:指定范围内的任意单个字符
#!/bin/bash
case $1 in
1)
echo "one"
;;
2)
echo "two"
;;
3)
echo "three"
;;
*)
echo "none"
;;
esac
sh case.sh 2
sh case.sh 4
自定义函数(一般不在函数里面调用)
function 函数名(){
....
}
引用自定义函数文件时,使用source func.sh
有利于代码的重用性;
函数传递参数;
函数的返回值,只能是数字.
fun.sh
#!/bin/bash
#-------
function test(){
echo "this is a function"
}
function.sh
#!/bin/bash
##调用函数脚本所在路径
source /usr/local/shell/fun.sh
##传递的参数,用于调用函数
test
date命令
显示当前时间
格式化输出 +%Y-%m-%d
格式%s表示自1970-01-01 00:00:00以来的秒数
指定时间输出 date --date='2009-01-01 11:11:11'
指定时间输出 date --date='3 days ago'
date "+%Y-%m-%d %H:%M:%S"
获取时间戳(秒级别的)计算当前时间与2017-11-29之间时间间隔多少分钟、秒、毫秒,将时间转换成时间戳的差值再除以相应的值而获取相差的时间
date --date="2017-11-29"
date +%s
date --date="2017-11-29" +%s
规范
注释代码
## Check if new_pass is empty or not
if [ ! -z $NEW_PASS ]
then
## If not empty set the password and pass expiry
echo $NEW_PASS | passwd --stdin $NEW_USER
chage -M $NEW_CHAGE $NEW_USER
chage -d 0 $NEW_USER
fi
使用 $(command) 进行命令替换
DATE=`date +%F`
#推荐
DATE=$(date +%F)
出错退出前描述问题
trap "echo '<====' exist this shell '===>'" EXIT