十六周二次课

1、 shell脚本介绍

Shell是什么

Shell是一种脚本语言,和传统语言C,Python...相比还是比较简单的。

可以使用逻辑判断,循环等语法

可以自定义函数

shell是系统命令的集合

shell脚本可以实现自动化运维,能大大增加我们的运维效率

shell脚本概念

编辑

shell和shell脚本有什么区别?确切一点说,Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。 Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言(就是你所说的shell脚本)。作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。

脚本简介

shell脚本

打开文本编辑器(可以使用vi/vim命令来创建文件),新建一个文件test.sh,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用php写shell 脚本,扩展名就用php好了。

输入一些代码,第一行一般是这样: [1] 

1

2

#!/bin/bash

echo "Hello World !"

"#!" 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。

echo命令用于向窗口输出文本。

 


2、 shell脚本结构和执行

1.  Shell脚本的第一行必须是:#!/bin/bash#!/bin/bash,因为能够识别本机的命令。这样才能另一台机器就也能够执行了,所以文件的第一行才要写这样的声明,shell脚本是在本机执行的话,倒是可以省略掉"#!" 是一个约定的标记,后面跟着的/bin/bash是告诉系统这个脚本需要使用/bin/bash解释器来执行。因为不同语言所编写的脚本对应的解释器都不一样,但是都需要使用 "#!" 来作为标记。简单来说就是告诉系统这是一个什么语言写的脚本。

      Shell脚本的文件名称是以.sh为后缀,shell中的注释符是井号“#”,,注意区别“#!”和“#”,前者是标记,后者才是注释符。除第一行外,剩下以#开头的大多只是作为解释说明用。要注意的是,#!/bin/bash写在文件的第一行才是被当做声明,如果写了两行#!/bin/bash,那么第二行就会被当做注释

2、执行shell脚本的方法有四种:

(1)sh Hello.sh =bash Hello.sh                                            #查看并执行用bash(sh)来执行脚本

(2)./script.sh                                                                #利用小数点来执行shell脚本

(3)chmod a+x Hello.sh; ./Hello.sh                       #赋予执行的权限,并查看shell脚本。可以当做一个二进制文件直接执行。

(4)source script.sh                                                # 利用source来执行hell脚本

注意:前面两种方式其实都是一样的:都是在当前父进程下的子进程中执行,子进程完成后,子进程中的各项变量或操作将会结束而不会传回到父进程中。

例子:

可以看到,执行后再看脚本中两个变量,在父进程中不起作用!

备注: 如果在script2.sh文件里面执行script1.sh的脚本,那么就是执行.  ./script1.sh   [中间有空格]

而通过第四种方式执行(source test.sh)的话,在父进程中就起作用了:

这就是直接执行与用source命令执行的区别,前者只作用于子进程本身,后者则作用于整个父进程

因此:如要想不注销系统,并让全局配置文件生效,则必须用source命令:

比如说: 在全局配置文件中/etc/profile添加了JAVA_HOME,要让他对整个环境生效

export JAVA_HOME=/usr/java/jdk1.7.0_75

就必须执行source /etc/profile

3. 查看脚本执行过程 bash -x 1.sh      # 每一个“+”代表执行的命令,后面跟着命令的执行结果。
 查看脚本是否语法错误  bash -n 1.sh

4、sh和bash实际上是同一个命令,因为sh是bash的软连接文件。

执行命令ll /bin/sh,发现sh其实只是bash的软连接。

[root@localhost shell]# ll /bin/sh

lrwxrwxrwx. 1 root root 4 10月 20 08:08 /bin/sh -> bash

[root@localhost shell]# ll /bin/bash

-rwxr-xr-x. 1 root root 960392 8月   3 2016 /bin/bash

5.通配符 再shell中比较特殊意义,它们被称作是shell元字符或通配符。

*、?和[]常用语文件名扩展;      

 !是历史命令符;

<、>、>>、<&和|符则用于标准I/O重定向管道。
为了防止这些字符被shell解释,他们必须用反斜杠或者引号进行引用。
如:rm *; ls ??; cat file [1-3];!!
echo “how are you?”
echo oh boy\!

显示输出
echo命令用户向屏幕显示输出。
echo “hello word \!”


局部变量 局部变量的作用域被限定在当前的shell中。
set ariable_name = value
set name = “Admin”

6.变量在shell中的使用案例。

局部变量 局部变量的作用域被限定在当前的shell中。
set ariable_name = value
set name = “Admin”


全局变量 全局变量又称环境变量。
setenv VARIABLE_NAME value
setenv PRINTER Shakespeare


提取变量值 可以使用$从变量中提取数值;
echo $variable_name
echo $name
echo $PRINTER


读取用户输入 特殊变量$<从用户输入中读取一行并将它赋值给一个变量
echo “who are you?”
set name = $<

参数 可以从命令中传递参数给脚本;得到它们的值有两种方法:位置参数和argv数组。
% scriptname arg1 arg2 arg3 ……
使用位置:
echo $1 $2 $3 arg1赋给$1,arg2赋给$2等;
echo $* 所有参数
使用argv数组:
echo $argv[1] $argv[2] $argv[3] 
echo $argv[*] 所有参数  
echo $#argv 参数个数

7.查看脚本是否语法错误 bash -n 01.sh

(我们为了看到实验效果,故意写一个错的脚本,在for循环的结尾少写一个done)

[root@congji shell]# cat 01.sh 

1  #!/bin/bash

2  for i in `seq 1 10`

3  do

4     echo $i

[root@congji shell]# sh -n 01.sh                 

01.sh:行6: 语法错误: 未预期的文件结尾

它提示报错,那我们加上done试试,

[root@congji shell]# sh -n 01.sh          (执行后没有报错,也没有返回值)

[root@congji shell]# sh  01.sh 

1  #!/bin/bash

2  for i in `seq 1 10`

3  do

4     echo $i


3、 date命令用法

date是一个与时间日期相关的命令,如果直接使用的话,是显示当前系统的日期时间

[root@congji ~]# date 

2018年 01月 11日 星期四 00:00:07 CST

关于表示时间符号的解释:

%Y  4位的年份(Year)

%y  2位的年份

%M  表示当前的分钟(Minute)

%m  表示当前的月份(Month)

%D   以2位的格式输出当前的年月日

%d   表示当前的日期(Date)

%F   输出当前的年月日,以 - 为分隔

%H   输出当前的小时时间

%h   输出当前的月份

%s   输出时间戳

%S   输出秒

%T   输出当前时间,以 : 为分隔

%W   输出本周是今年的第几周

%w   输出本周是这个月的第几周

那么加上参数他会怎么显示呢

[root@localhost ~]# date +%Y                   (显示4位数年)

2018

[root@localhost~]# date +%y                    (显示2位数年)

18

[root@localhost~]# date +%m                    (显示月份)

01

[root@localhost~]# date +%d                    (显示日期)

11

[root@localhost ~]# date +%Y%m%d                  (把他们综合在一起就会显示当前日期)

20180111

[root@localhost ~]# date +%D                    (以月,日,年的方式显示时间)

01/11/18

[root@localhost ~]# date +%F                     (以年-月-日的方式显示时间)

2018-01-11

既然有年月日,那就有分钟和小时

[root@localhost~]# date +%H                      (显示当前的小时)

00

[root@localhost~]# date +%M                       (显示当前的分钟)

20

[root@localhost~]# date +%S                        (显示当前多少秒)

36

[root@localhost ~]# date +%s                       (这是一个时间戳,举例1970年1月1日0点过去了多少秒)

1515601302

我们可以把所有的参数组合起来显示多少秒,也可以直接加T显示多少秒,用T显示的更为清楚

[root@localhost~]# date +%H%M%S

002910

[root@localhost~]# date +%T

00:29:16

把全部的参数组合起来:

[root@localhost ~]# date +%Y-%m-%d/%H:%M:%S     (为了更清晰的看到结果,我们给中间加上了分隔符)

2018-01-11/00:35:58

[root@localhost~]# date +%F/%T              (同样我们用F和T也能显示出同样的效果)

2018-01-11/00:36:45

所以我们得出结论

date +%Y-%m-%d = date +%F

date  +/%H:%M:%S = date +%T

[root@localhost ~]# date +%w        (显示今天是周几)

4

[root@localhost ~]# date +%W        (显示今天是今年的第几周)

02

用cal命令,像日历一样显示时间,会显示日期。

[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

现在有一个实例,今天是1月11日,你要写一个切割日志脚本,在每天的0点切割日志,但是我们都知道,一到0点,时间就会显示后一天。所以我们要学会增加减少,我们以减少为例。

[root@localhost ~]# date

2018年 01月 11日 星期四 00:54:00 CST

[root@localhost~]# date -d "-1 day"                    (显示当前时间提前一天)

2018年 01月 10日 星期三 00:54:02 CST

[root@localhost~]# date -d "-1 month"                    (显示当前时间提前一月)

2017年 12月 11日 星期一 00:54:12 CST

[root@localhost ~]# date -d "-1 min"                     (显示当前时间提前一分钟)

2018年 01月 11日 星期四 00:53:19 CST

[root@localhost ~]# date -d "+1 day" +%F                      打印一天后的日期

[root@localhost ~]# date -d "-1 day" +%F                       打印一天前的日期:

[root@localhost ~]# date -d "-1 month" +%F                              打印一个月前的日期

[root@localhost ~]#date -d "-1 min"                                      打印一分钟前

[root@localhost ~]#date -d "-1 years" +%F                             打印一年前的日期

[root@localhost ~]#date -d "-1 hour" +%T                                       打印一小时前

[root@localhost ~]#date +%s -d "2017-09-06 06:52:16"                                  把一个日期转换成时间戳

显示时间戳是%s,让时间戳显示成日期,使用date命令。

[root@localhost~]# date +%s

1515603280

[root@localhost ~]# date -d @1515603280 

2018年 01月 11日 星期四 00:54:40 CST

 


4、 shell脚本中的变量

      shell脚本中的变量和其他编程语言中的变量含义是一样的,都是用来存储一个数据,然后使用变量名就可以进行调用了,shell脚本的语法和其他脚本的语法类似,都不需要使用分号作为语句的结束。

shell脚本定义变量的规则:

  • 首个字符必须为字母(a-z,A-Z)。

  • 中间不能有空格,可以使用下划线(_)。

  • 不能使用标点符号。

  • 不能使用bash里的关键字(可用help命令查看保留关键字)。

定义一个变量:

a=10

name=”lisi”

调用变量时需要在变量名前面加上$:

echo $a

echo $name

只读变量:

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

删除变量:

使用 unset 命令可以删除变量里的数据。语法:unset name,因为变量的内容被删除,所以输出的是空的。

变量类型:

运行shell时,会同时存在三种变量:

  1) 局部变量    局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

  2) 环境变量    所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

  3) shell变量    shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了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] 

链接:http://blog.51cto.com/zero01/1983828

    另一个版本的介绍:http://blog.51cto.com/13407306/2069395

猜你喜欢

转载自my.oschina.net/u/3803405/blog/1800543
今日推荐