2018-07-27笔记( shell学习)

20.1 shell脚本介绍

•shell是一种脚本语言
•可使用逻辑判断、循环等语法
•能够自定义函数
•shell是系统命令的集合
•shell脚本能够实现自动化运维,能大大增长咱们的运维效率

shell是什么
shell是一个命令解释器,它在操做系统的最外层,负责直接与用户对话,把用户的输入解释给操做系统,并处理各类各样的操做系统的输出结果,输出到屏幕返回给用户。这种对话方式能够是交互的方式(从键盘输入命令,能够当即获得shell的回应),或非交互(执行脚本程序)的方式
什么是shell脚本?
当linux命令或语句不在命令下执行(严格说,命令行执行的语句也是shell脚本),而是经过一个程序文件执行时,该程序就被称为shell脚本或shell程序,shell程序很相似DOS系统下的批处理程序(扩展名*.bat)。用户能够在shell脚本中敲入一系列的命令或命令语句组合。这些命令、变量和流程控制语句等有机的结合起来就造成了一个功能很强大的shell脚本。
shell脚本语言的种类
在UNIX/LINUX中主要有两大类shell。linux

•Bourne shell包括sh、ksh和bash。
•Bourne shell (sh)
•Korn shell (ksh)
•Bourne Again shell (bash)
•POSIX shll (sh)
•C shell包括csh和tcsh。
•C shell (csh)
•TEXES/TOPS C shell(tcsh)

shell脚本语言是若类型语言,较为通用的shell有标准的Bourne shell(sh)和C shell(csh)。其中Bource shell(sh)已经被bash shell取代。
查看系统的shell。shell

[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash #功能更强大
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh

20.2 shell脚本结构和执行

•开头须要加#!/bin/bash,指定是哪一个解释器
•以#开头的做为解释说明
•脚本的名字以.sh结尾,用于区分这是一个shell脚本
•执行方法有几种
shell脚本的创建
在linux系统中,shell脚本(bash shll程序)一般是在编辑器(如vi/vim)中编写,由Unix/Linux命令、bash shell命令、程序结构控制语句和注释等内容组成
脚本开头(第一行)
一个规范的shell脚本在脚本第一行会指出由哪一个程序(解释器)来执行脚本中的内容,这一行内容在linux bash编程中通常为:
#! /bin/bash

#! /bin/sh <==255个字符之内
其中开头的"#!"字符又称为幻数,在执行bash脚本的时候,内核会根据"#!"后的解释器来肯定该用哪一个程序解释这个脚本的内容。注意,这一行必须在每一个脚本顶端的第一行,若是不是第一行则为脚本注释行
脚本注释
在shell脚本中,跟在(#)井号后面的内容表示注释,用来对脚本进行注释说明,注释部分不会被当作程序执行,仅仅是给用户看,系统解释器是看不到的,更不会执行。注释可自成一行,也能够跟在脚本命令后面与命令在同一行
shell脚本的执行
当shell脚本运行时,它会先查找系统环境变量ENV,该变量指定了环境文件(一般是.bashrc、.bash_profile、/etc/bashrc、/etc/profile等),而后从该环境变量文件开始执行脚本,当读取了ENV的文件后,shell会开始执行shell脚本中的内容。
特殊技巧:设置crond任务时,最好把系统环境变量在定时任务脚本中从新定义,不然,一些系统环境变量将不会被加载
执行说明
第一种方法是当脚本文件自己没有可执行权限(即文件x位为-号)时常使用的方法,或者文件开头没有指定解释器。
例如:编程

[root@localhost ~]# cat test.sh 
echo 'i am shell'
[root@localhost ~]# sh test.sh 
i am shell
[root@localhost ~]# bash test.sh 
i am shell

第二种方法须要先将脚本文件的权限改成可执行(即文件加X位),具体方法:chmod u+x script-name或chmod 755 script-name。而后经过脚本路径就能够直接执行脚本。
例如:vim

[root@localhost ~]# ll test.sh 
-rw-rw-r--. 1 root root 1217 7月  27 13:57  test.sh
[root@localhost ~]# ./test.sh #使用第二种方式,"./"在当前目录下执行test.sh脚本文件,没法使用tab自动补全
-bash: ./test.sh: Permission denied 
给test.sh添加可执行权限。
[root@localhost ~]# chmod u+x test.sh 
[root@localhost ~]# ./test.sh 
i am shell

第三种放法一般是使用source或"."点号读入或加载指定的shell脚本文件(如test.sh),而后,依次执行指定shell脚本文件test.sh中的全部语句
例如:bash

[root@lamp ~]# . test.sh 
i am shell
[root@lamp ~]# source test.sh 
i am shell

说明:若是但愿父shell调用子shell的变量、函数等,用source或"."点号执行脚本less

20.3 date命令用法

命令:date
date 能够用来显示或设定系统的日期与时间。
命令参数运维

-d<字符串>:显示字符串所指的日期与时间。字符串先后必须加上双引号; 
-s<字符串>:根据字符串来设置日期与时间。字符串先后必须加上双引号;只有root权限才能设置,其余只能查看 
-u:显示GMT; 
--help:在线帮助; 
--version:显示版本信息

日期格式字符串列表编辑器

%H 小时(以00-23来表示)。 
%I 小时(以01-12来表示)。 
%K 小时(以0-23来表示)。 
%l 小时(以0-12来表示)。 
%M 分钟(以00-59来表示)。 
%P AM或PM。 
%r 时间(含时分秒,小时以12小时AM/PM来表示)。 
%s 总秒数。起算时间为1970-01-01 00:00:00 UTC。 
%S 秒(以本地的惯用法来表示)。 
%T 时间(含时分秒,小时以24小时制来表示)。 
%X 时间(以本地的惯用法来表示)。 
%Z 市区。 
%a 星期的缩写。 
%A 星期的完整名称。 
%b 月份英文名的缩写。 
%B 月份的完整英文名称。 
%c 日期与时间。只输入date指令也会显示一样的结果。 
%d 日期(以01-31来表示)。 
%D 日期(含年月日)。 
%j 该年中的第几天。 
%m 月份(以01-12来表示)。 
%U 该年中的周数。 
%w 该周的天数,0表明周日,1表明周一,异词类推。 
%x 日期(以本地的惯用法来表示)。 
%y 年份(以00-99来表示)。 
%Y 年份(以四位数来表示)。 
%n 在显示时,插入新的一行。 
%t 在显示时,插入tab。 
MM 月份(必要) 
DD 日期(必要) 
hh 小时(必要) 
mm 分钟(必要)
ss 秒(选择性)

实例:
•年月日ide

[root@localhost ~]# date +"%Y-%m-%d" 
2018-07-29
[root@localhost ~]# date +"%y-%m-%d" 
18-07-29

•输出昨天、前天,明天等的日期:函数

[root@localhost ~]# date -d "+1 day " +"%Y-%m-%d"
2018-07-28
[root@localhost ~]# date -d "+2 day " +"%Y-%m-%d"
2018-07-27
[root@localhost ~]# date -d "-1 day " +"%Y-%m-%d"
2018-07-30

•加减操做:

date -d "+1 day" +%Y%m%d   #显示前一天的日期 
date -d "-1 day" +%Y%m%d   #显示后一天的日期 
date -d "-1 month" +%Y%m%d #显示上一月的日期 
date -d "+1 month" +%Y%m%d #显示下一月的日期 
date -d "-1 year" +%Y%m%d  #显示前一年的日期 
date -d "+1 year" +%Y%m%d  #显示下一年的日期

设定时间:

date -s          #设置当前时间,只有root权限才能设置,其余只能查看 
date -s 20120523 #设置成20120523,这样会把具体时间设置成空00:00:00 
date -s 01:01:01 #设置具体时间,不会对日期作更改 
date -s "01:01:01 2012-05-23" #这样能够设置所有时间 
date -s "01:01:01 20120523"   #这样能够设置所有时间 
date -s "2012-05-23 01:01:01" #这样能够设置所有时间 
date -s "20120523 01:01:01"   #这样能够设置所有时间

•显示日历

[root@localhost ~]# cal
      七月 2018     
日 一 二 三 四 五 六
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

20.4 shell脚本中的变量

•当脚本中使用某个字符串,屡次频繁而且字符串长度很长时,就应该使用变量代替
•使用条件语句时,常使用变量 if [ $a -gt 1];then ...;fi
•引用某个命令的结果时,用变量替代 n=wc -l 1.txt
•写和用户交互的脚本时,变量也是必不可少的 read -p "lnput a number:" n; echo $n 若是没有写这个n, 能够直接使用$REPLY
•内置变量 $0,$1,$2... $0表示脚本自己,$1 第一个参数,$2第二个... $#: 表示参数个数
•数学运算a=1;b=2;c=$($a+$b)或者$[$a+$b]

20.5 shell脚本中的逻辑判断

Shell脚本中,充满着各类逻辑判断,是脚本中必备的
•if逻辑判断格式

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

•数学逻辑判断表达式:

-gt (>);    大于    great than
-lt(<);      小于     less than
-ge(>=);  大于或等于   
-le(<=);   小于或等于
-eq(==);  等于     equal
-ne(!=)    不等于  not equa
- - - - - - - - - - - - - - - - - - - - - -
方括号里面不能使用数学运算符<,>,=,等,两边中间都要有空格
要使用这些符号,只能使用两个括号(()),不用空格
例如
if [ $a -gt $b ]等同if (($a>$b))
if [ $a -lt 5 ]等同if (($a<5))
if [ $b -eq 10 ]等if (($b==10))

•多个条件组合-a,-o

-a表示而且,所有条件都成立
-o或者或者,知足一个条件成立
[root@localhost ~]# a=5;if [ $a -gt 4 -a $a -lt 6 ];then echo ok;fi
ok
[root@localhost ~]# a=5;if [ $a -gt 5 -o $a -lt 6 ];then echo ok;fi
ok

•可使用 && || 结合多个条件

条件A&&条件B:A而且B
条件A||条件B:A或者B
if [ $a -gt 5 ] && [ $a -lt 10 ]; then
if [ $b -gt 5 ] || [ $b -lt 3 ]; then

•if逻辑判断例子
格式1:if 条件 ; then 语句; fi

#!/bin/bash
a=5
if [ $a -gt 3 ]
then
       echo "ok"
fi

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

#!/bin/bash
a=5
if [ $a -gt 3 ]
then
    echo "ok"
else
    echo "nook"
fi

格式3:if …; then … ;elif …; then …; else …; fi

#!/bin/bash
a=5
if [ $a -lt 4 ]
then
    echo "<4"
elif [ $a -lt 6 ]
#注意elif能够嵌套屡次的
then
    echo "<6 && >4"
else
    echo "nook"
fi

20.6 文件目录属性判断

在shell中一般要和文件或者目录打交道,那么对于他们的属性判断十分重要

[ -f file ]判断是不是普通文件,且存在   
[ -d file ] 判断是不是目录,且存在  
[ -e file ] 判断文件或目录是否存在  
[ -r file ] 判断文件是否可读   
[ -w file ] 判断文件是否可写  
[ -x file ] 判断文件是否可执行

例子:

#!/bin/bash
file="/tmp/1.txt"
if [ -e $file ]
then 
       echo $file exist
else
      touch $file

&& ||特殊用法,省略if

1.txt不存在,&&表示前一条命令执行成功,才会执行后面的命令
[root@localhost ~]# [ -e 1.txt ]&&touch 1.txt
[root@localhost ~]# ll
总用量 4
-rw-------. 1 root root 1418 4月  26 05:41 anaconda-ks.cfg
drwxr-xr-x  2 root root   60 6月  18 11:40 src1
1.txt不存在,||表示前一条命令执行不成功,才会执行后面的命令
[root@localhost ~]# [ -e 1.txt ]||touch 1.txt
[root@localhost ~]# ll
总用量 4
-rw-r--r--  1 root root    0 7月  29 22:13 1.txt
-rw-------. 1 root root 1418 4月  26 05:41 anaconda-ks.cfg
drwxr-xr-x  2 root root   60 6月  18 11:40 src1

20.7 if特殊用法

if [ -z "$a" ]  这个表示当变量a的值为空时会怎么样
if [ -n "$a" ]  表示当变量a的值不为空
if grep -q '123' 1.txt; then  表示若是1.txt中含有'123'的行时会怎么样
if [ ! -e file ]; then 表示文件不存在时会怎么样
if (($a<1)); then …等同于 if [ $a -lt 1 ]; then… 
[ ] 中不能使用<,>,==,!=,>=,<=这样的符号

例子:
if [ -z “$a” ] 这个表示当变量a的值为空时会怎么样

#!/bin/bash
n='wc -l /tmp/1.txt'
if [ $n -lt 100 ]
then
       echo "line num less than 100"
fi
# 若是/tmp/1.txt文件为空,或者被删除的话,脚本就会运行出错,出现bug
应该加上一个判断条件
#!/bin/bash
n='wc -l /tmp/1.txt'
if [  -z "$n" ]
# [  -z "$n" ] 等同[ ! -n "$n" ],!表示取反
then
       echo "error"
       exit
elif [ $n -lt 100 ]
then
        echo "line num less than 100"
fi

或者
#!/bin/bash
if [ ! -f /tmp/1.txt ]
then
       echo "/tmp/1.txt is not exist"
       exit
fi

n='wc -l /tmp/1.txt'
if [ $n -lt 100 ]
then
        echo "line num less than 100"
fi

if [ -n “$a” ] 表示当变量a的值不为空,也能够判断文件,判断文件时能够不加双引号

if [ -n 01.sh ]; then echo "ok"; fi
另外
#!/bin/bash
if [ -n "$b" ]
then  
       echo $b
else
        echo "b is null"
fi

一条命令也能够做为判断条件。判断user1用户是否存在

if grep -wq 'user1'  /etc/passwd; then echo "user1 is exist"; else useradd user1;fi 
#grep -w 精准匹配单词,加-q能够不显示过滤信息

20.8/20.9 case判断

case判断格式

case 变量名 in
    value1)
      commond1
      ;;
    value2)
      commod2
      ;;
    value3)
      commod3
      ;;
esac

在case中,能够在条件中使用“|”,表示或的意思,如:

2|3)
    commond
    ;;

例子: 输入一个同窗的分数,判断成绩是否及格,优秀

[root@localhost sbin]# vim case1.sh
#!/bin/bash
read -p "Please input a number: " n
# read -p 是读取用户的输入数据,定义到变量里面
if [ -z "$n" ]
then
    echo "error not input"
    exit 1
#“exit 1”表示非正常运行致使退出程序
#退出以后,echo $?会返回1值,表示程序退出是由于出错了
fi

n1=`echo $n|sed 's/[0-9]//g'`
#判断用户输入的字符是否为纯数字
#若是是数字,则将其替换为空,赋值给$n1
if [ -n "$n1" ]
then
echo "Please input a number."
exit 1
#判断$n1不为空时(即$n不是纯数字)再次提示用户输入数字并退出
fi

#若是用户输入的是纯数字则执行如下命令:
if [ $n -lt 60 ] && [ $n -ge 0 ]
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 "不及格"
        ;;
    2)
        echo "及格"
        ;;
    3)
        echo "良好"
        ;;
    4)
        echo "优秀"
        ;;
    *)
        echo "The number range is 0-100."
        ;;
esac

运行结果

[root@localhost shell]# sh case1.sh
Please input a number: 
error not input
[root@localhost shell]# sh case1.sh
Please input a number: 12a23
Please input a number.
[root@localhost shell]# sh case1.sh
Please input a number: 45
不及格
[root@localhost shell]# sh case1.sh
Please input a number: 65
及格
[root@localhost shell]# sh case1.sh
Please input a number: 85
良好
[root@localhost shell]# sh case1.sh
Please input a number: 95
优秀
[root@localhost shell]# sh case1.sh
Please input a number: 120
The number range is 0-100.

20.10 for循环

•格式:

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

例子:
•用for循环计算1到100的总和

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

#输出的结果
[root@localhost shell]# sh for.sh 
5050

•文件列表循环

[root@localhost shell]# cat for2.sh 
#!/bin/bash
cd /etc/
for a in `ls /etc/`
do
    if [ -d $a ]
    then
        ls -d $a
    fi
done
#for循环是以空格、回车符做为分割符分割。

20.11/20.12 while循环

•语法 while 条件; do ...; done
例子:
用while循环检测系统1分钟的负载,若是大于,发邮件通知

#!/bin/bash
while :
#while 跟冒号表示死循环
do
    load=`w|head -1 |awk -F 'load average: ' '{print $2}'| cut -d . -f1`
    if [ $load -gt 10 ]
    then
        top|mail -s "load is high:$load" admin@163.com
    fi
    sleep 30
done

循环判断输入的是否纯数字

#!/bin/bash
while :
do
  read -p "Please input a number:" n
  if [ -z "$n" ]
  then
      echo "You did not enter the number."
      continue
  fi
  n1=`echo $n|sed 's/[0-9]//g'`
  if [ ! -z "$n1" ]
  then
      echo "You can only enter a pure number."
      continue
  fi
  break
done
echo $n

20.13 break跳出循环

break表示跳出循环,断续执行后面的语句
例子

#!/bin/bash
for i in `seq 1 5`
do
  echo $i
  if [ $i -eq 3 ]
  then
      break
  fi
  echo $i
done
echo aaaaaa

运行结果

[root@localhost ~]# sh break.sh
1
1
2
2
3
aaaaaa

能够看到上例中,只循环到第3次的时候,跳出了循环,直接执行了echo aaaaaa的语句

20.14 continue结束本次循环

continue结束本次循环,不执行后面的语句,直到循环结束

[root@localhost etc]# 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 aaaaaa

运行结果

[root@localhost etc]# sh continue.sh 
1
1
2
2
3
4
4
5
5
aaaaaa

能够看到循环到第3次的时候,没有执行后面的语句,直到循环结束

20.15 exit退出整个脚本

exit退出脚本

[root@localhost etc]# cat exit.sh 
#!/bin/bash
for i in `seq 1 5`
do
  echo $i
  if [ $i -eq 3 ]
  then
      exit
  fi
  echo $i
done
echo aaaaaa

运行结果

[root@localhost etc]# sh exit.sh 
1
1
2
2
3

能够看到第三次,直接退出了脚本

相关文章
相关标签/搜索