shell 脚本的编辑基础

      shell脚本是Linux运维工程师必须掌握的技能之一,shell脚本的使用让我们更好的操作Linux系统,方便了我们的执行。

一,编程基础

编程基本概念

编程逻辑处理方式:顺序执行,循环执行,选择执行

程序:指令+ 数据

shell 编程:过程式、解释执行

shell程序:提供了编程能力,解释执行

程序编程风格:

     过程式:以指令为中心,数据服务于指令

     对象式:以数据为中心,指令服务于数据

程序的执行方式

     计算机:运行二进制指令;

编程语言的基本结构:

      数据存储:变量、数组

      表达式: a + b

      语句:if

编程语言:

     低级:汇编

     高级:

         编译:高级语言–> 编译器–> 目标代码  : java,C#

         解释:高级语言–> 解释器–> 机器代码  : shell, perl, python

编程程序语言分类

强类型:定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误

如 java,python

弱类型:无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用

如:bash  不支持浮点数

二,shell 脚本基础

shell脚本规范和用途:

shell 脚本是包含一些命令或声明,并符合一定格式的文本文件

格式要求:首行shebang 机制

      shell脚本:#!/bin/bash; 文件名以 .sh 结尾

      Python: #!/usr/bin/python; 文件名以 .py 结尾

      Perl   :#!/usr/bin/perl ; 文件名以 .pl 结尾

shell 脚本的用途有:

      自动化常用命令

      执行系统管理和故障排除

      创建简单的应用程序

      处理文本或文件

创建shell 脚本

第一步:使用文本编辑器来创建文本文件

      第一行必须包括shell 声明序列:#!: #!/bin/bash

      添加注释:注释以# 开头

第二步:运行脚本

      给予执行权限,在命令行上指定脚本的绝对或相对路径

      直接运行解释器,将脚本作为解释器程序的参数运行

脚本调试

bash -n /path/to/some_script

检测脚本中的语法错误

bash -x /path/to/some_script

调试执行

三,脚本变量的基础

变量(变量的内容是可以更改的,它可以存储很多类型的数据)

变量:命名的内存空间

     数据存储方式:

            字符:

            数值:整型,浮点型

变量:变量类型

     作用:1 、数据存储格式;2 、参与的运算;3 、表示的数据范围

     类型:

           字符

           数值:整型、浮点型

变量命名法则:

     1 、不能使程序中的保留字:例如if, for;

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

     3 、见名知 义

     4 、统一命名规则:驼峰命名法(多个单词命名,分为大,小驼峰,大驼峰是每个单词的第一个字母大写,小驼峰是除了第一个单词小写其他单词的第一个字母大写)

{

sleep 休眠:在脚本中执行 sleep + 时间 可以有时间查看父子进程,sleep默认时间为秒。

定义变量时不能带空格,必须用双引号扩起来才可以。

echo默认是一行,加双引号就可以原原本本显示出来。

}

四,变量的范围简介

根据变量的生效范围等标准:

本地变量:生效范围为当前shell 进程;对当前shell 之外的其它shell 进程,包括当前shell 的子shell 进程均无效

      变量赋值:name=‘value’

      可以使用引用value:

           (1)  可以是直接字串; name=“root"

           (2)  变量引用:name="$USER"

           (3)  命令引用:name=` COMMAND `, name =$(COMMAND)

      变量引用:${name}, $name

           "" :弱引用,其中的变量引用会被替换为变量值

           '' :强引用,其中的变量引用不会被替换为变量值,而保持原字符串

      显示已定义的所有变量:set

      删除变量:unset name

环境变量:生效范围为当前shell 进程及其子进程局部变量:生效范围为当前shell 进程中某代码片断( 通常指函数)

      变量声明、赋值:

          export name=VALUE

          declare -x name=VALUE

      变量引用:$name, ${name}

      显示所有环境变量:

           export

           env

           printenv

      删除:unset name

      bash 有许多内建的环境变量:PATH, SHELL, USRE,UID,HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1

只读变量:只能声时,但不能修改和删除(一般使用在常量身上)

      readonly name

      declare -r name

(declare -rx name  定义一个即使常量,也是环境变量)

位置变量:$1, $2, … 来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数

       在脚本代码中调用通过命令行传递给脚本的参数

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

       $0:  命令本身

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

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

       $#:  传递给脚本的参数的个数

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

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

             linecount="$(wc -l $1| cut -d' ' -f1)"

             echo "$1 has $linecount lines."

      特殊变量:$?, $0, $*, $@, $#

      basename  + 文件名

      basename的语法是:basename[选项][参数]

              选项:为有路径信息的文件名,如/home/test/test.txt

              参数:指文件扩展名

五,bash运算

算术运算:help let(bash虽然不支持浮点,但是还是支持加减乘除的)

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

         实现算术运算:

               (1) let var= 算术表达式

               (2) var=$[ 算术表达式]

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

               (4) var=$(expr arg1 arg2 arg3 …)

               (5) declare –i var =  数值  (需要先申明数值,在进行计算)

               (6) echo ‘ 算术表达式’ | bc

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

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

         echo $[$RANDOM%50]  :0-49

(echo $[RANDOM%50+1] :1-50    %50+1 :是0-49整体性的+1,不是单个的49+1)

         $?是查看上一个命令的状态,

         expr使用乘号需要把乘号转义和加空格  如:expr 2 \* 3

赋值

         增强型赋值:+=, -=, *=, /=, %=

{

% : 在算术运算中,这个是求模操作符,即两个数进行除法运算后的余数;

}

         let varOPERvalue

              例如:let count+=3(自己先加3 后再给自己赋值)

         自增,自减:

              let var+=1

              let var++

              let var-=1

              let var–

逻辑运算

true 1, false  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 ,第二个必须要参与运算;

          cmd1 && cmd2

          cmd1 成功,将执行cmd2

          cmd1 失败,将不执行cmd2

     短路或 :(||)

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

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

          cmd1 成功,将不执行cmd2

          cmd1 失败,将执行cmd2

     异或:^

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

{

短路与  和   普通与 的区别

cmd1 &&  cmd2

短路与:  cmd1 为真时  ,执行 cmd2 ;  cmd1为假时  ,不执行 cmd2  直接退出。

普通与: cmd1 不管是真是假,cmd2 都要执行 。

短路或  和   普通或 的区别

cmd1 || cmd2

短路与 : cmd1 为真时,可以不用执行 cmd2 直接退出; cmd1 为假时,执行 cmd2 。

普通与 : cmd1 不管是真是假,cmd2 都要执行。

}

六,bash的退出状态

进程使用退出状态来报告成功或失败

      0 代表成功,1 -255 代表失败

      $?  变量保存最近的命令退出状态(最后一条的命令的状态)

例如:

      $ ping -c1 -W1 hostdown &> /dev/null

      $ echo $?

(ping  -c1  代表拼一个)(ping -W1    一秒,默认为是五秒,在局域网一般最多需要一秒连接的显示信息就能返回,在互联网时间稍长一点)

退出状态码

bash 自定义退出状态码

exit [n] :自定义退出状态码;(在脚本中(exit)执行的是子shell )

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

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

七,bash 的测试类型

条件测试

判断某需求是否满足,需要由测试机制来实现;

专用的测试表达式需要由测试命令辅助完成测试过程;

评估布尔声明,以便用在条件性执行中

      若真,则返回0

      若假,则返回1

测试命令:

      test EXPRESSION   (test $a = $b    测试$a 和$b 是否相同时 $a 和$b的前后必须要有空格,要是没有就成了赋值了)

      [ EXPRESSION ]

      [[ EXPRESSION ]]    ([[ $a ]] 测试$a 是否定义过值)

注意:EXPRESSION 前后必须有空白字符

test 命令

     长格式的例子:

          $ test "$A" == "$B" && echo "Strings are equal"

          $ test “$A” -eq “$B” \

          && echo "Integers are equal"

     简写格式的例子:

           $ [ "$A" == "$B" ] && echo "Strings are equal"

           $ [ "$A" -eq "$B" ] && echo "Integers are equal"

条件性的执行操作符

根据退出状态而定,命令可以有条件地运行

      &&  代表条件性的AND THEN

      || 代表条件性的OR ELSE

例如:

      $ grep -q no_such_user /etc/passwd \|| echo 'No such user'

      No such user

     
$ ping -c1 -W2 station1 &> /dev/null \> && echo
"station1 is up" \> || (echo 'station1 is unreachable'; exit 1)

      station1 is up

数值测试:

     -gt:  是否大于;

     -ge:  是否大于等于;

     -eq:  是否等于;

     -ne:  是否不等于;

     -lt:  是否小于;

     -le:  是否小于等于;

字符串测试:

     == :是否等于;

     >: ascii 码是否大于ascii码

     <:  是否小于

     !=:  是否不等于

     =~:  左侧字符串是否能够被右侧的PATTERN所匹配(右侧是要使用扩展正则表达式)

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

{

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

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

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

}

文件测试

     存在性测试

          -a FILE :同-e

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

     存在性及类别测试

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

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

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

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

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

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

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

      文件权限测试:(是以实际的权限为标准,不是看设的权限的。)

          -r FILE :是否存在且可读

          -w FILE:  是否存在且可写

          -x FILE:  是否存在且可执行

      文件特殊权限测试:

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

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

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

      文件大小测试:

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

      文件是否打开:

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

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

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

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

双目测试:

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

{

        FILE1 -nt FILE2: FILE1 是否新于FILE2;

        FILE1 -ot FILE2: FILE1 是否旧于FILE2;

}(比的是文件的修改时间)

组合测试条件

      第一种方式:

            COMMAND1 && COMMAND2  并且

            COMMAND1 || COMMAND2  或者

            ! COMMAND 非

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

      第二种方式:

            EXPRESSION1 -a EXPRESSION2  并且

            EXPRESSION1 -o EXPRESSION2  或者(or)

            ! EXPRESSION

            必须使用测试命令进行;

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

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

八,聚集命令

有两种聚集命令的方法:

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

子shell :(date; who | wc -l ) >>/tmp/trace  (所有的输出都被发送给单个STDOUT 和STDERR)

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

(0)
AN0519AN0519
上一篇 2016-08-22
下一篇 2016-08-22

相关推荐

  • 登录后经常出现You have new mail in /var/spool/mail/root的提示

    安装完LINUX后经常使用终端远程登录,登录后经常出现You have new mail in /var/spool/mail/root的提示,很是烦人。 这东西到底是做什么用的呢?经过查询才知道这是LINUX的邮年提示功能。LINUX会定时查看LINUX各种状态做汇总,每经过一段时间会把汇总的信息发送的root的邮箱里,以供有需之时查看。 那要怎么去掉这麻…

    系统运维 2017-08-05
  • 第二周学习总结

    写在最前 通过上一周对计算机系统、Linux发展的学习,我们认识到了Linux是一个一切皆文件的内核系统。那么怎样去操作系统上的各文件来达到你想要的目的呢?今天的总结就是帮助我们更快的达成目标。 文件管理类命令的分类 对于这类命令主要分为两类: 操作类:touch、cp、mv 查看类:cat、tac、head、tail、less、more touch 功能描…

    2017-12-16
  • Linux权限基本介绍,管理

     Linux权限机制采用UGO模式。其中 u(user)表示所属用户、g(group)表示所属组、o(other)表示除了所属用户、所属组之外的情况。 u、g、o 都有读(read)、写(write)、执行(excute) 三个权限,所以UGO模式是三类九种基本权限。         用命令 ls …

    Linux干货 2017-07-22
  • N22-第三周博客作业

    1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。 2、取出最后登录到当前系统的用户的相关信息。 3、取出当前系统上被用户当作其默认shell的最多的那个shell。 4、将/etc/passwd中的第三个字段数值最大的后10个用户的信息全部改为大写后保存至/tmp/maxusers.txt文件中。 5、取出当前主机的…

    Linux干货 2016-08-29
  • LVS-dr模型

    网络拓扑图 需三台主机 要在主机rs上做系统内核的限制 vs主机上配置vip和在rs主机上在lo环配置vip 那个先开始都行 rs主机上在lo环配置vip必须要晚于于在rs主机做内核的限制 在VS主机上配置VIP #ifconfig ens33:0 172.18.0.33 network 255.255.255.2550 broadcast 172.18.0…

    Linux干货 2017-05-17
  • 马哥教育网络班22期+第8周课程练习

    week8: 1、请描述网桥、集线器、二层交换机、三层交换机、路由器的功能、使用场景与区别。 网桥也叫桥接器,是连接两个局域网的一种存储/转发设备,它能将一个大的LAN分割为多个网段, 或将两个以上的LAN互联为一个逻辑LAN,使LAN上的所有用户都可访问服务器。 它工作于OSI(开放系统互联参考模型)参考模型第二层,即“数据链路层”。 集线器的英文称为“H…

    Linux干货 2016-10-09