Shell脚本编程入门

认识Shell

Shell原意为贝壳

Linux系统中的shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当一个命令解释器的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。

可以使用命令查看当前使用的是哪种shell以及当前Linux系统中都支持哪些shell种类。

 

查看当前系统使用的shell

Shell脚本编程入门

 

查看当前Linux系统所支持的shell种类

Shell脚本编程入门

其中/bin/bash是目前大多数Linux版本采用的默认shellBash的全称为Bourne Again Shell,是最受欢迎的开源软件项目之一。

常见的shell解释器程序有很多种,使用不同的shell时,其内部指令、命令行提示等方面会存在一些区别。

 

Shell脚本

只要将平时使用的各种Linux命令按顺序保存到一个文本文件,然后添加可执行权限,这个文件就成为一个shell脚本了。

编写一个恰到好处的shell脚本程序,可以批量处理、自动化地完成一系列维护任务、大大减轻管理员的负担。

周期性的任务可以通过Crond服务来管理,而步骤复杂、操作繁琐的任务可以使用Shell脚本来批量处理,两相结合就可以非常灵活、自主地完成各种系统运维工作。Shell脚本负责具体的备份操作,Crond服务负责控制备份周期。

 

1、脚本的编写

Shell脚本编程入门

Shell脚本主要由开头部分、注释部分以及语句部分组成

1)开头

“#!/bin/bash”是一行特殊的脚本声明,表示此行以后的语句通过/bin/bash程序来解释执行。

符号“#!”用来告诉系统它后面的参数是用来执行该文件的程序。

2)注释

其它以”#”开头的语句表示注释信息,建议在程序中使用注释,即使过了长时间也能很快的了解脚本的用途。

3)语句

Linux各种命令的集合

 

2、脚本的执行

编写完成shell脚本后,需要赋予执行权限

Shell脚本编程入门

执行此脚本文件后,输出结果与依次执行这两条命令是相同的,从而实现了批量处理的自动化过程。

Linux还提供了执行shell脚本的方式——指定某个shell来解释脚本语句,或者通过内部命令source(或点号”.”)来加载文件的源代码执行。

例如,使用”sh first.sh”“. first.sh”都可以执行firsh.sh脚本中的语句。

Shell脚本编程入门

注意:以上三种执行方式不添加执行权限也可以执行文件

 

3、脚本调试

bash -n /path/to/scriptfile    检测脚本中的语法错误

bash -x /path/to/scriptfile    调试执行

 

Shell变量

Shell变量用来存放系统和用户需要使用的特定参数(值)。而且这些参数可以根据用户的设定或系统环境的变化而相应变化。

常见的Shell变量的类型包括自定义变量、环境变量、预定义变量、位置变量。

1、自定义变量

自定义变量是由系统用户自己定义的变量,只在用户自己的Shell环境中有效,因此又称为本地变量。

 

1)定义新的变量

定义变量的基本格式为变量名=变量值,等号两边没有空格。

[root@localhost ~]# name=tom

[root@localhost ~]# age=20

Shell脚本编程入门

 

变量名称命名规则:

a.不能使程序中的保留字:例如if, for

b.只能使用数字、字母及下划线,且不能以数字开头

c.见名知义

d.统一命名规则:驼峰命名法

 

2)查看和引用变量的值

Shell脚本编程入门

 

2、环境变量

环境变量指的是出于运行需要而由Linux系统提前创建的一类变量,主要用于设置用户的工作环境,包括用户宿主目录、命令替换路径、用户当前目录、登录终端等。环境变量的值由linux系统自动维护,会随着用户状态的改变而改变。

使用env命令可以查看当前工作环境下的环境变量,对于常见的一些环境变量应了解其各自的用途。

例如USER表示用户标识、HOME表示用户的宿主目录、LANG表示语言和字符集、PWD表示当前所在的工作目录、PATH表示命令搜索路径….

 

查看当前Linux系统中所有的环境变量

   blob.png

可以用命令修改环境变量的搜索路径,这样写完shell脚本以后可以直接输入脚本名称直接执行,不用每次输入文件的路径。

 

临时修改:只对当前终端有效

Shell脚本编程入门

 

永久修改:永久有效

修改家目录下的隐藏文件.bash_profile,添加指定的搜索路径即可,搜索路径之间用“:”分隔,添加完成后需要重新读取该配置文件让其生效。

Shell脚本编程入门

 

重新读取配置文件使其立即生效

Shell脚本编程入门

Shell脚本编程入门

 

将搜索路径添加完成后直接输入文件名即可运行成功

Shell脚本编程入门

 

PATH的搜索顺序:从左到右依次搜索,

Shell脚本编程入门

同样在/usr/bin下面写一个同名的脚本文件,执行时依然执行/testdir/script目录下的文件,当把hash缓存清空后,即执行了/usr/bin目录下的first.sh文件,如果把缓存再次清空,执行脚本文件报错,清空缓存后,有可以执行了。

从此可见,缓存(hash)中的命令优先于搜索路径,如果缓存中有这条命令,就不去搜索PATH变量,文件不存在也执行hash,会报错;清空缓存后,按照PATH变量的搜索顺序依次查找,当PATH变量有多个可以匹配,执行先匹配到,匹配到第一个脚本时不再往下搜索。

 

环境变量的配置文件

全局配置文件:/etc/.bash_profile

个人配置文件:~/.bash_profile

 

3、预定义变量

预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。预定义变量使用$符号和另一个符号组合表示,较常用的几个预定义变量如下:

$#:表示命令行中位置参数的个数。

$*:传递给脚本的所有参数,全部参数合为一个字符串。

$@: 传递给脚本的所有参数,每个参数为独立字符串

$@ $* 只在被双引号包起来的时候才会有差异

$?:表示前一条命令执行后的返回状态,0表示成功,非0表示失败。

$0:表示当前执行的脚本或程序的名称。

 

示例:备份目录数据,并显示备份信息

Shell脚本编程入门

 

4、位置变量

 位置变量:位置变量也称为位置参数,在脚本代码中调用通过命令行传递给脚本的参数

当执行命令行操作时,第一个字符表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。

$1, $2, …:对应第1、第2等参数, shift [n]换位置

 

示例:计算两个数值的和

Shell脚本编程入门

 

示例:判断给出的文件的行数

Shell脚本编程入门

 

   定义只读变量

只读变量:只能声明,但不能修改和删除

readonly name

declare -r name

 

示例:定义只读变量

Shell脚本编程入门

注意:只读变量同样只在当前终端中有效

 

变量赋值的特殊操作

1)双引号(

双引号主要起了一个界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来,否则会报错;其他情况下双引号通常可以省略。

Shell脚本编程入门

在双引号范围内,使用“$”符号可以引用其他变量的值(变量引用),从而能够直接调用现有变量的值来赋值给新的变量。

Shell脚本编程入门

Shell脚本编程入门

2)单引号(

当要赋值的内容中包含$ \等具有特殊含义的字符时,应使用单引号括起来。在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待。但赋值内容中包含单引号时,需使用“\’”符号进行转义,以免冲突。

Shell脚本编程入门

 

3)反撇号(`

反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围内必须是能够执行的命令行,否则将会出错。

Shell脚本编程入门

需要注意的是,使用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以改用“$()”来代替反撇号操作,以解决嵌套的问题。

Shell脚本编程入门

 

变量的作用范围

1、设置局部变量

默认情况下,新定义的变量只在当前的Shell环境中有效,因此成为局部变量。当进入子程序或新的子Shell环境时,局部变量将无法再使用。

Shell脚本编程入门

 

2、设置全局变量

为了使用户定义的变量在所有的子Shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为全局变量可以同时制定多个变量名称作为参数(不需使用$符合),变量名之间以空格分隔。

Shell脚本编程入门

 

使用export导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了,也可以将之前的局部变量设置使用export命令设置为全局变量,使其在子shell中可以调用。

Shell脚本编程入门

注意:设置全局变量后,子进程可以调用父进程的变量,反之则不可以。

 

条件测试

使用专门的测试工具test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值0表示条件成立)。

test 条件表达式

[ 条件表达式 ]

 

两种方式作用完全相同,但后者更为常用,也更贴近编程习惯。需要注意的是,方括号与表达式之间需要至少一个空格进行分割。

根据需要测试的条件类别不同,条件表达式也不一样。比较常用的条件操作包括文件测试、整数值比较、字符串比较,以及针对多个条件的逻辑测试。

执行条件测试操作后,通过预定义变量”$?“可以获得测试命令的返回状态值,从而判断该条件是否成立。echo $?查看返回状态值。

 

1、文件测试

    存在性测试

    -e FILE: 文件存在性测试,存在为真,否则为假

    -a FILE:同-e

     

    存在性及类别测试

    -b FILE  是否存在且为块设备文件

    -c FILE  是否存在且为字符设备文件

    -d FILE  是否存在且为目录文件

    -f FILE   是否存在且为普通文件

    -h FILE -L FILE:存在且为符号链接文件

    -p FILE  是否存在且为命名管道文件

    -S FILE  是否存在且为套接字文件

     

    文件权限测试

    -r  测试当前用户是否有权限读取(Read

    -w         测试当前用户是否有权限写入(Write

    -x 测试是否这只有可执行权限(Excute

     

    文件特殊权限测试

    -g FILE:是否存在且拥有sgid权限

    -u FILE:是否存在且拥有suid权限

    -k FILE:是否存在且拥有sticky权限

     

    文件大小测试

    -s FILE: 是否存在且非空;

     

    文件是否打开

    -t fd:        fd表示文件描述符是否已经打开且与某终端相关

    -N FILE:文件自动上一次被读取之后是否被修改过

    -O FILE:当前有效用户是否为文件属主

    -G FILE:当前有效用户是否为文件属组

     

    双目测试

    FILE1 -ef FILE2: FILE1FILE2是否指向同一个设备上的相同inode

    FILE1 -nt FILE2: FILE1是否新于FILE2

    FILE1 -ot FILE2: FILE1是否旧于FILE2

 

2、数值比较

-eq   1个数等于(Equal)第2个数

-ne   1个数不等于(Not Equal)第2个数

-gt    1个数大于(Greater Than)第2个数

-lt    1个数小于(Lesser Than)第2个数

-le     1个数小于或等于(Lesser or Equal)第2个数

-ge  1个数大于或等于(Lesser or Equal)第2个数

 

3、字符串比较

=     1个字符串与第2个字符串相同

!=    1个字符串与第2个字符串相同,其中!符号表示取反的意思

-z    检查字符串是否为空(Zero),对于未定义或赋予空值的变量将视为空串。

==    是否等于;

>:      ascii码是否大于ascii

<:      是否小于

!=:     是否不等于

=~:     左侧字符串是否能够被右侧的PATTERN所匹配

注意: 此表达式一般用于[[ ]]中;

 

-z "STRING":字符串是否为空,空为真,不空为假

-n "STRING":字符串是否不空,不空为真,空为假

注意:用于字符串比较时的用到的操作数都应该使用引号

 

算术运算

bash中的算术运算

+, -, *, /, %取模(取余) , **(乘方)

实现算术运算:

let var=算术表达式

var=$[算术表达式]

var=$((算术表达式))

var=$(expr arg1 arg2 arg3 …)

declare –i var = 数值

echo ‘算术表达式’ | bc

乘法符号有些场景中需要转义, *

bash有内建的随机数生成器: $RANDOM 1-32767

echo $[$RANDOM%50] 0-49之间随机数

Shell脚本编程入门

 

赋值

增强型赋值:

+=, -=, *=, /=, %=

let varOPERvalue

例如:let count+=3            自加3后自赋值

自增,自减:

let var+=1

let var++

let var-=1

let var–

 

示例:算术运算

Shell脚本编程入门

 

示例:j自增自减运算

Shell脚本编程入门

 

    逻辑测试

&&:逻辑与,表示而且的意思,只有当前后两个条件都成立时,真个测试命令的返回值才为0。使用test命令测试时,&&可改为-a

||:逻辑与,表示或者的意思,只有前后两个条件有一个成立时,整个测试命令的返回值为0。使用test名测试时,||可改为-o

!:逻辑否,表示的意思,只有当指定的条件不成立时,正测试命令的返回值才为0

 

逻辑运算

true, false

1, 0

与:&&

1 1 = 1

1 0 = 0

0 1 = 0

0 0 = 0

或:||

1 1 = 1

1 0 = 1

0 1 = 1

0 0 = 0

非:

! 1 = 0

! 0 = 1

短路运算

短路与:

第一个为0,结果必定为0

第一个为1,第二个必须要参与运算;

短路或:

第一个为1,结果必定为1

第一个为0,第二个必须要参与运算;

异或: ^

异或的两个值,相同为假,不同为真

 

聚集命令

有两种聚集命令的方法

复合式: date; who | wc –l          命令会一个接一个地运行

shell (date; who | wc -l )  >> /tmp/trace

所有的输出都被发送给单个STDOUTSTDERR

 

组合测试条件

第一种方式:

COMMAND1 && COMMAND2 并且

COMMAND1 || COMMAND2 或者

! COMMAND

如: [ -e FILE ] && [ -r FILE ]

第二种方式:

EXPRESSION1 -a EXPRESSION2 并且

EXPRESSION1 -o EXPRESSION2 或者

! EXPRESSION

必须使用测试命令进行;

# [ -z “$HOSTNAME” -o $HOSTNAME "==\"localhost.localdomain" ] && hostname www.magedu.com

# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

 

示例:判断两个变量的大小

Shell脚本编程入门

 

退出状态

进程使用退出状态来报告成功或失败,$? 变量保存最近的命令退出状态

0  代表成功

1255  代表失败

 

示例:ping一个ip地址,并查看其返回

Shell脚本编程入门

 

退出状态码

bash自定义退出状态码

exit [n]:自定义退出状态码;

注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

      如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

 

示例:根据测试条件返回状态码

Shell脚本编程入门

 

read命令:接受用户输入

使用read来把输入值分配给一个或多个shell变量:

read  [选项]  [参数]

-p    指定要显示的提示信息

-t    指定读取值时等待的时间(秒)

-n    读取用户输入的前几个字符

-s    隐藏用户的输入字符

-r    允许输入包含反斜杠

-d    -d选项指定的字符作为结束符,如空格、特殊符号

read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量。

read -p “Enter a filename: “ FILE

 

示例:编写修改当前用户的密码脚本

Shell脚本编程入门

使用-s选项可隐藏用户要输入的字符信息,如密码等信息

 

 

原创文章,作者:cyh5217,如若转载,请注明出处:http://www.178linux.com/33473

(0)
上一篇 2016-08-12 09:01
下一篇 2016-08-12 09:01

相关推荐

  • Vim编辑器初步接触

    一、概要     vim(IMproved)编辑器是vi(visual interface)编辑器的增强版,它是Linux系统编辑文本文件重要的工具之一,也是最基础的编辑工具。它可以执行输出、删除、查找、替换、块操作等众多文本操作。学会它之后,你使用Linux系统的路将更加平坦。 二、使用方法   …

    Linux干货 2015-04-03
  • tree命令 -P选项的用法探讨

         tree命令是以树状图的形式来列出目标文件夹的目录结构,包括所有路径和所有文件名,如图1所示。                               &n…

    2017-05-29
  • 第二周- -问题总结

    前言:这周学习了文件的基本操作、用户和权限管理、重定向和管道。 1.在centos6.9当中,创建虚拟机的时候,网络无法获取地址,ping也不通,出现  device eth0 does not seem to be present, delaying initialization 答:(1).虚拟机启动出错,就把这个虚拟机删除掉重新建立,系统虚拟…

    2017-07-23
  • 关于Raid的各种类型特点概要

    关于Raid需要了解掌握的要点

    Linux干货 2017-11-26
  • 初入linux

    一、认识linux 1、在windows中通过盘符区分文件存放位置,而linux中没有盘符之说,只有文件和文件夹 2、在linux中,万物从根开始,没有后缀之说 二、文件系统的目录结构 /:根目录 /boot:系统启动的相关配置文件 /dev:设备文件 块设备:随机访问,数据块为单位 字符设备:线性访问,按字符为单位 设备号:主设备号(major)和次设备号…

    Linux干货 2017-05-20
  • linux 系统日志管理

         在linux系统上面,系统可以记录从开机到当前系统上面何时发生了那些事情,并将其分类,分级别写到特定的日志文件当中,如系统自身产生的问题,用户登录信息,网络数据信息等等。我们可以根据这些日志信息来解决系统方面的错误,网络服务问题等等。日志对于安全来说,非常重要,它记录了系统每天发生的各种各样的事情,你可以通过它来检查错…

    2017-08-14

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-12 14:39

    学习态度端正,博客不仅写的完善而且有自己的想法,通过自己的思路汇总,足以见其对知识的理解深刻,望后期能持续学习,提升自我。