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)
cyh5217cyh5217
上一篇 2016-08-12 09:01
下一篇 2016-08-12 09:01

相关推荐

  • 马哥教育网络班第21期+第四周课程作业

    1. 复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限。 cp -r /etc/skel /home/tuser1 chmod –R 700 /home/tuser1 2. 编辑/etc/group文件,添加组hadoop。 echo &q…

    Linux干货 2016-08-01
  • linux计划任务

    任务计划的分类: 一次性的任务计划:只执行一次 周期性的任务计划:每隔一定的周期去做相同的事情 设置任务计划功能的工具:at和crontab at:专门处理一次性的计划任务 crontab:根据定义的周期信息,循环做一些事情 batch:系统自行选择空闲时间去执行此处指定的任务 At命令: 查看atd状态和启动atd服务及其配置文件路径: centos6:s…

    2017-09-09
  • PHP数组实际占用内存大小的分析

    我们在前面的php高效写法提到,尽量不要复制变量,特别是数组。一般来说,PHP数组的内存利用率只有 1/10, 也就是说,一个在C语言里面100M 内存的数组,在PHP里面就要1G。下面我们可以粗略的估算PHP数组占用内存的大小,首先我们测试1000个元素的整数占用的内存: <?php      &nb…

    系统运维 2015-05-28
  • 2班jackcui20160802作业

    1、每日课堂笔记总结 2、预习 3、每日课堂pdf练习 4、在/data/testdir里创建的新文件自动属于g1组,组g2的成员如:alice能对这些新文件有读写权限,组g3的成员如:tom只能对新文件有读权限,其它用户(不属于g1,g2,g3)不能访问这个文件夹。 [root@centos7 /]# groupadd g1 [root@centos7 /…

    Linux干货 2016-08-05
  • linux用户与组管理

    一、linux用户与组管理的基本介绍 1、任何一个用户想要使用Linux系统都要向管理员申请一个账号,对这些账号的管理即是对用户的管理,所谓组,就是多个账号的集合。用户和组管理可以提高用户的管理效率、工作效率以及系统的安全性,比如将同一个部门的成员放在一个组里并设置权限,这样可有效的对资源共享,同时可以避免其他部门的人恶意破坏。 2、用户和组的管理内容一般有…

    Linux干货 2016-08-02
  • shell脚本基础

    编程基础 v程序:指令+数据 v程序编程风格: 过程式:以指令为中心,数据服务于指令(适合小型程序) 对象式:以数据为中心,指令服务于数据(适合大型程序) vshell程序:提供了编程能力,解释执行 程序的执行方式 v计算机:运行二进制指令; v编程语言: 低级:汇编 高级: 编译:高级语言–>编译器–>目标代码 java…

    Linux干货 2016-08-15

评论列表(1条)

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

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