您的位置:首页 > 运维架构 > Shell

Shell编程一

2018-07-29 14:19 429 查看

Shell编程

shell脚本介绍

shell是一种脚本语言。它既有自己的语法规制,可以使用逻辑判断、循环等语法,也可以自定义函数。
shell是系统命令的集合,并且通过主机的语法可以对命令进行判断等。
shell脚本可以实现自动化运维,它能大大增加我们的运维效率。

shell脚本结构

shell脚本结构
开头需要加#!/bin/bash #!/bin/bash是告诉系统通过/bin/bash解析器来解析操作脚本的
以#开头的行作为解释说明
脚本的名字以.sh结尾,用于区分这是一个shell脚本

执行方法

[root[@localhost](https://my.oschina.net/u/570656) shell]# vim hello.sh
[root[@localhost](https://my.oschina.net/u/570656) shell]# cat !$
cat hello.sh
#!/bin/bash
echo 'hello world'
echo 'How are you?'

执行方法有两种:
chmod +x 1.sh; ./1.sh
sh 1.sh

[root[@localhost](https://my.oschina.net/u/570656) shell]# sh hello.sh
hello world
How are you?
[root[@localhost](https://my.oschina.net/u/570656) shell]# chmod +x hello.sh
[root[@localhost](https://my.oschina.net/u/570656) shell]# ./hello.sh
hello world
How are you?
[root@localhost shell]#

查看脚本执行过程

[root@localhost shell]# sh -x hello.sh
+ echo 'hello world'
hello world
+ echo 'How are you?'
How are you?
[root@localhost shell]#

查看脚本是否语法错误

[root@localhost shell]# sh -n hello.sh
[root@localhost shell]# echo 'for' >> hello.sh
[root@localhost shell]# sh -n hello.sh
hello.sh:行5: 未预期的符号 `newline' 附近有语法错误
hello.sh:行5: `for'
[root@localhost shell]#
这里可见 原先的脚本是无误的,在我加入了一个 for后,提示报错,原因是for循环没有写完整

date命令方法

[root@localhost shell]# date
2018年 07月 23日 星期一 23:56:39 CST
[root@localhost shell]#
date 显示当前系统时间 在shell脚本中才用于标志时间

命令				含义
date +%Y	  	  年(4位)
date +%y		  年(2位)
date +%m		  月
date +%d		  日
date +%D		  以 月/日/年 格式显示日期
date +%F		  以 年-月-日 格式显示日期
date +%H		  小时
date +%M		  分钟
date +%S		  秒
date +%T		  以时:分:秒 格式显示时间 等于 date +%H:%M:%S
date +%s		  时间戳 表示距离1970年1月1日到现的秒数
date +%w		  这个星期的第几周
date +%W		  今年的第几周
date +%h		  月份缩写 等于 date +%b
date -d “-1 day”	一天前
date -d “+1 day”	一天后
date -d “-1 year”	一年前
date -d “-1 month”	一个月前
date -d “-1 hour”	一小时前
date -d “-1 min”	一分钟前

只显示日期

[root@localhost shell]# date +%Y%m%d
20180723
[root@localhost shell]#
[root@localhost shell]# date +%D
07/23/18
[root@localhost shell]# date +%F
2018-07-23
[root@localhost shell]#

显示时间

[root@localhost shell]# date +%T
00:00:04
[root@localhost shell]#

显示时间戳

[root@localhost shell]# date +%s
1532361632
[root@localhost shell]#

用时间戳来显示日期

[root@localhost shell]# date -d @1532361532
2018年 07月 23日 星期一 23:58:52 CST
[root@localhost shell]# date -d @1532361632
2018年 07月 24日 星期二 00:00:32 CST
[root@localhost shell]#

指定时间来显示对应的时间戳

[root@localhost shell]# date +%s -d'2018-07-29 08:59:00'
1532825940
[root@localhost shell]#

显示前一天的时间

[root@localhost shell]# date -d '-1 day' +%F
2018-07-23
[root@localhost shell]# date -d '+1 day' +%F
2018-07-25
[root@localhost shell]#
后一天的时间即是 +1

显示一个小时前的时间

[root@localhost shell]# date -d '-1 hour' +%T
23:05:31
[root@localhost shell]# date -d '+1 hour' +%T
01:05:36
[root@localhost shell]#
一个小时后的时间即是 +1

shell脚本中的变量

当脚本中使用某个字符串较频繁并且字符串长度很长时就应该使用变量代替,既可以更加工作效率,也可以方便更改
使用条件语句时,常使用变量 if [ $a -gt 1 ]; then … ; fi
引用某个命令的结果时,用变量替代 n=`wc -l 1.txt`
写和用户交互的脚本时,变量也是必不可少的 read -p “Input a number: “ n; echo $n 如果没写这个n,可以直接使用$REPLY
内置变量 $0, $1, $2… $0表示脚本本身文件名,$1表示第一个参数,$2 第二个 …. $#表示参数个数
数学运算a=1;b=2; c=$(($a+$b))或者$[$a+$b]

Shell脚本的逻辑判断

语法格式

格式1:if 条件;then 语句; fi
格式2:if 条件; then 语句; else 语句; fi
格式3:if 条件1; then 语句1;elif 条件2; then 语句2; else 语句3; fi

格式1演示:

脚本形式

[root@localhost shell]# vim if_1.sh
[root@localhost shell]# sh !$
sh if_1.sh
YES
[root@localhost shell]# cat !$
cat if_1.sh
#!/bin/bash
a=5
if [ $a > 4 ]
then
echo 'YES'
fi
[root@localhost shell]#

命令行形式

[root@localhost shell]# a=5
[root@localhost shell]# if [ $a > 3 ];then echo 'yes';fi
yes
[root@localhost shell]#
不推荐,建议使用脚本方式

或者

[root@localhost shell]# a=5
[root@localhost shell]# if [ $a > 3 ]
> then echo 'yes'
> fi
yes
[root@localhost shell]#
不推荐,建议使用脚本方式

格式2演示:

[root@localhost shell]# vim if_2.sh
[root@localhost shell]# sh if_2.sh
No
[root@localhost shell]# cat !$
cat if_2.sh
#!/bin/bash
a=1
b=2
if [ $a -gt $b ]
then
echo 'Yes'
else
echo 'No'
fi
[root@localhost shell]#

格式3演示:

意思为符合条件1则执行语句1,不符合则再判断是否符合条件2,都不符合则执行语句3

[root@localhost shell]# vim if_3.sh
[root@localhost shell]# sh if_3.sh
the num < 3
[root@localhost shell]# cat !$
cat if_3.sh
#!/bin/bash
a=2
if [ $a -eq 3 ]
then
echo "the num = 3"
elif [ $a -gt 3 ]
then
echo "the num > 3"
else
echo "the num < 3"
fi
[root@localhost shell]#

参数		数学符号		含义
-gt			>			大于(greater than)
-lt			<			小于 (less than)
-eq			==			等于(equal)
-ge			>=			大于等于
-le			<=			小于等于
-ne			!=			不等于

可以使用 && || 结合多个条件
if [ $a -gt 5 ] && [ $a -lt 10 ] 	&&表示并且
if [ $b -gt 5 ] || [ $b -lt 3 ] 	||表示或者

文件目录属性判断

参数					含义
[ -f file ]			判断是否是普通文件,且存在
[ -d file ]			判断是否是目录,且存在
[ -e file ]			判断文件或目录是否存在
[ -r file ]			以当前用户来判断文件是否可读
[ -w file ]			以当前用户来判断文件是否可写
[ -x file ]			以当前用户来判断文件是否可执行

判断是否存在

[root@localhost shell]# vim file1.sh
[root@localhost shell]# cat file1.sh
#!/bin/bash
f="/tmp/test"
if [ -f $f ]
then
echo '$f exist'
else
touch $f
fi
[root@localhost shell]# sh file1.sh
[root@localhost shell]# sh file1.sh
$f exist
[root@localhost shell]#
第一次执行时不存在,所以走第二个条件,创建文件
第二次执行时已存在,所以走一个条件,提示已存在

判断是否可读

[root@localhost shell]# vim file2.sh
[root@localhost shell]# sh file2.sh
/tmp/test readable
[root@localhost shell]# cat !$
cat file2.sh
#!/bin/bash
f="/tmp/test"
if [ -r $f ]
then
echo "$f readable"
fi
[root@localhost shell]#

if特殊用法

参数				含义
[ -z “$a” ]			表示当变量a的值为空
[ -n “$a” ]			表示当变量a的值不为空
[ ! -n “$a” ]	    表示当变量a的值为空   ! 取反
中括号中不能使用<,>,==,!=,>=,<=这样的符号

判断变量是否不为空

[root@localhost shell]# vim file3.sh
[root@localhost shell]# sh file3.sh
ok
[root@localhost shell]# cat file3.sh
#!/bin/bash
f=/tmp/test
if [ -n "$f" ]
then
echo ok
fi
[root@localhost shell]#

使用命令来做判断条件

[root@localhost shell]# if grep -wq 'root' /etc/passwd;then echo root exist;fi
root exist
[root@localhost shell]#
grep -w 'root'只搜索root此单词 -q 不在屏幕打印出来

case判断

语法格式

case  变量名 in
value1)
command
;;
value2)
command
;;
*)
commond
;;
esac

在条件中使用 | 表示 或 的意思

2|3)
command
;;

判断成绩脚本

[root@localhost shell]# cat case1.sh
#!/bin/bash
read -p "Please input number: " n
#让用户输入数字
if [ -z "$n" ]
then
echo "Please input number: "
exit 1
fi
#判断用户是否没填数字
n1=`echo $n|sed 's/[0-9]//g'`
if [ ! -z "$n1" ]
then
echo "Please input number: "
exit 1
fi
#判断用户是否填纯数字
if [ $n -lt 60 ]
then
tag=1
elif [ $n -ge 60 ] && [ $n -lt 80 ]
then
tag=2
elif [ $n -ge 80 ] && [ $n -lt 90 ]
then
tag=3
elif [ $n -ge 90 ] && [ $n -le 100 ]
then
tag=4
else
tag=0
fi
#给分数赋值给tag
case $tag in
1)
echo "rubbish"
;;
2)
echo "just so so"
;;
3)
echo "good"
;;
4)
echo "perfect"
;;
*)
echo "The number range is 0-100"
;;
esac
[root@localhost shell]#

[root@localhost shell]# vim case1.sh
[root@localhost shell]# sh case1.sh
Please input number: 50
rubbish
[root@localhost shell]# sh case1.sh
Please input number: 70
just so so
[root@localhost shell]# sh case1.sh
Please input number: 90
perfect
[root@localhost shell]# sh case1.sh
Please input number: 88
good
[root@localhost shell]# sh case1.sh
Please input number: 988
The number range is 0-100
[root@localhost shell]#

for循环

语法格式:

for 变量名 in 条件; do ...;done

计算0到100的总和

[root@localhost shell]# vim for1.sh
[root@localhost shell]# sh for1.sh
5050
[root@localhost shell]# cat !$
cat for1.sh
#!/bin/bash
sum=0
for i in `seq 1 100`
do
sum=$[$i+$sum]
done
echo $sum
[root@localhost shell]#

遍历/data/目录并把目录列出来

[root@localhost shell]# vim for2.sh
[root@localhost shell]# ls /data/
mysql
[root@localhost shell]# sh for2.sh
auto.cnf     ib_logfile1		localhost-relay-bin.000005  master.info		relay-log.info
ibdata1      lan			localhost-relay-bin.000006  mysql		test
ib_logfile0  localhost.localdomain.err	localhost-relay-bin.index   performance_schema	zrlog
[root@localhost shell]# cat !$
cat for2.sh
#!/bin/bash
cd /data
for i in `ls /data`
do
[ -d $i ] && ls $i
done
[root@localhost shell]#

while循环

语法格式

while 条件; do … ; done

提示让用户只能输入数字

[root@localhost shell]# vim while1.sh
[root@localhost shell]# sh while1.sh
Please input a number: 1as
Please input number!
Please input a number: we
Please input number!
Please input a number:
Please input sth!
Please input a number: 123
123
[root@localhost shell]# cat !$
cat while1.sh
#!/bin/bash
while :
do
read -p "Please input a number: " n
if [ -z "$n" ]
then
echo "Please input sth!"
continue
fi
##判断用户是否直接回车
n1=`echo $n|sed 's/[0-9]//g'`
# echo $n|sed 's/[0-9]//g 把数字给过滤掉来判断是否有其他字符
if [ -n "$n1" ]
then
echo "Please input number!"
continue
fi
#判断用户是否输入纯数字
echo $n
break
done
[root@localhost shell]#

break && continue && exit

break

[root@localhost shell]# vim break.sh
[root@localhost shell]# sh break.sh
1
1
2
2
3
666
[root@localhost shell]# cat !$
cat break.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
break
fi
echo $i
done
echo 666
[root@localhost shell]#
$i 在 数字 1-5 内循环,一旦 $i 等于 3 ,那么就跳出 循环

continue

[root@localhost shell]# vim continue.sh
[root@localhost shell]# sh continue.sh
1
1
2
2
3
4
4
5
5
666
[root@localhost shell]# cat !$
cat continue.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
continue
fi
echo $i
done
echo 666
[root@localhost shell]#
忽略当次循环,进行下一次循环。 所以第二次打印 数字3 没有打印,直接跳出了

exit

[root@localhost shell]# vim exit.sh
[root@localhost shell]# sh exit.sh
1
1
2
2
3
[root@localhost shell]# cat !$
cat exit.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
exit 1
fi
echo $i
done
echo 666
[root@localhost shell]#
exit退出整个脚本,不在进行循环,

[root@localhost shell]# echo $?
1
[root@localhost shell]#
退出脚本后,进行echo $? 返回值是1

小结

break,continue都是在for while循环中使用的
break出现时候会跳出本次循环 直接忽略掉了break后面的代码
continue出现时候也会忽略掉了continue后面的代码并重新再来执行循环
exit直接跳出脚本 一般exit 后面会跟一个数字 给用户返回该值

扩展

select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Bash GNU sed Vim Relay GT