linux学习笔记: shell脚本编程相关(上)

前言 
unix/linux操作系统下的shell,是一种,其目的是提供一个用户与计算机相互交互的命令接口,通过输入各种命令,达到操作的目的。 
与此同时,shell支持控制流程,进而可以组合出各种各样的应用实例。

  • shell脚本的格式 

    • 首行shebang机制: 
      bash脚本,首行添加#!/bin/bash [options] 
      csh脚本,首行添加#!/bin/csh [options] 
      ksh脚本,首行添加#!/bin/ksh [options] 
      ……
    • 描述脚本的注释部分: 
      包括Author, Version, Date, Description,……该部分是非必须项,目的是为了让使用脚本的人能够比较清晰地了解该脚本的背景以及功能 
      ……
    • 脚本的正文部分: 
      包含命令与声明,以面向过程的形式组合在一起

脚本示例如下:

#!/bin/bash     #首行的shebang,表示使用bash编写脚本
#Author: AAA  #标注作者(格式规范,非必须)
#Version: 1.0   #标注版本(格式规范,非必须)
#Date: 2017-04-14   #标注日期(格式规范,非必须)
#Description: XXXXX...      #脚本功能描述(格式规范,非必须)

echo "Hello World"      #脚本正文部分

  • 编写脚本的一些规范 
    1. 脚本的第一行shebang注明调用的语言 
    2. 注释上一些信息,诸如: 文件名,功能描述,作者,版本…… 
    3. 变量名和函数名建议使用同一种命名法则 
    4. 有尽量多的注释说明程序的功能,单行注释写在代码行上部或者尾部 
    5. 代码做的修改要加必要的版本注释和功能说明 
    6. 脚本的控制流程里面建议要有缩进,使用一定数量的空格或者Tab 
    7. 文件名按照使用的语言,以.sh,.pl,.py等形式为后缀

  • 常用的符号

符号 描述
在单引号中所有特殊符号均无特殊含义
“” 在双引号中,除“$”“\”外其他特殊符号都无特殊含义
$() 在括号中使用系统命令
$ 调用变量的值
\ 转义符
$n 代表命令行的第n个参数,其中$0代表命令本身
$# 代表命令行中参数的个数
$* 代表命令行中所有的参数,把所有参数看成一个整体
$@ 代表命令行中的所有参数,把每个参数个别对待
$? 代表最后一次执行的命令的返回状态,返回0代表执行成功,否则不成功
$$ 代表当前进程的进程号
$! 代表后台运行的最后一个进程的进程号

  • 变量 
    用户自定义变量 *: 
    为局部变量,只对当前shell生效。默认类型为字符串类型。 
    定义:变量名=变量值,当变量中含有空格时,需要用引号引起来 
    声明:declare [+/-] [option] 变量名 
    选项: +取消属性 -设置属性 -i 整型 -a 数组 -r 只读 
    使用unset命令删除变量 
    更加详细的声明规则,可以使用help declare查询 
    数组 *: 
    定义数组: arr_name=(value1 value2 ….)或 使用arr_name[index]=value单独为元素赋值 
    注意: 
    数组元素放在小括号内,而不是大括号,元素之间使用空格分开,而不是逗号,元素下标从0开始 
    获取数组元素: {arr_name[index]} 索引号为index的元素 {array_name[*]}数组的所有元素 
    获取数组长度: ${#arr_name[*]} 
    数组切片:${arr_name[@]:start:length} 
    元素匹配替换:${arr_name[@]/before/after} 
    环境变量 *: 
    为全局变量,对子shell仍然有效,一般定义为大写,使用命令env或者set命令可以查询,用命令declare -x可以自定义环境变量,使用unset命令可以删除变量。常用的系统预定义的环境变量如下所示:
变量 描述
$PATH 命令的搜寻路径
$OLDPWD 前一个工作目录
$LANG 目前的工作环境语言
$BASH 目前使用的shell的绝对路径(默认为/bin/bash)
$BASH_VERSION 使用的shell解释器的版本
$HISTCONTROL 控制历史记录,常用的有ignoredups,erasedups,ignorespace,……
$OSTYPE 显示系统类型
$MAIL 存放mail的文件
$MAILCHECK 多久检查一下邮件
$PWD 当前路径
$SSH_TTY 当前登录的TTY
$SHLVL 当前SHELL在第几层
$RANDOM 输出一个随机整数

注:生成0-49之间的随机数可以用如下命令:

echo $[RANDOM%50]
  • 算数运算 
    bash支持简单的算数运算,实现方式如下:

    1. let r=9+9
    2. r=$[9+9]; r=$[VAR1+VAR2]
    3. r=$((9+9)); r=$((VAR1+VAR2))
    4. expr 8 + 3
    5. declare -i r=9+9
    6. echo “9+9” | bc
  • 赋值 
    可以使用如下几种赋值符号: 
    =, +=, -=, *=, /=, %= 
    使用示例如下:

[root@centos7-front1 scripts]# a=10;b=10
[root@centos7-front1 scripts]# echo $a $b
10 10
[root@centos7-front1 scripts]# let c=a++
[root@centos7-front1 scripts]# echo $c
10
[root@centos7-front1 scripts]# let d=++b
[root@centos7-front1 scripts]# echo $b
11
  • 字体颜色 
    字体颜色示例如下:

    echo -e “\033[30m 黑色字 \033[0m” 
    echo -e “\033[31m 红色字 \033[0m” 
    echo -e “\033[32m 绿色字 \033[0m” 
    echo -e “\033[33m 黄色字 \033[0m” 
    echo -e “\033[34m 蓝色字 \033[0m” 
    echo -e “\033[35m 紫色字 \033[0m” 
    echo -e “\033[36m 天蓝字 \033[0m” 
    echo -e “\033[37m 白色字 \033[0m”

    带背景的字体示例如下:

    echo -e “\033[40;37m 黑底白字 \033[0m” 
    echo -e “\033[40;37m 红底白字 \033[0m” 
    echo -e “\033[40;37m 绿底白字 \033[0m” 
    echo -e “\033[40;37m 黄底白字 \033[0m” 
    echo -e “\033[40;37m 蓝底白字 \033[0m” 
    echo -e “\033[40;37m 紫底白字 \033[0m” 
    echo -e “\033[40;37m 天蓝底白字 \033[0m” 
    echo -e “\033[40;37m 白底黑字 \033[0m”

  • 条件判断 
    使用test命令或者[]或者[[]]对条件进行测试 
    关于文件的判断,使用方式如下:
判断符 解释
-e 判断文件是否存在,如果存在则为真
-d 判断文件是否存在并且是否是目录(目录是一种特殊的文件),是则返回真
-f 判断文件是否存在并且是普通文件,是则返回真
-r 判断文件是否存在并且执行判断的用户是否对该文件有读的权限,是则返回真
-w 判断文件是否存在并且执行判断的用户是否对该文件有写的权限,是则返回真
-x 判断文件是否存在并且执行判断的用户是否对该文件有执行的权限,是则返回真
-nt 判断前面的文件是否比后面的文件新,是则返回真
-ot 判断前面的文件是否比后面的文件旧,是则返回真
-ef 判断前后两个文件的i节点是否相同,是则返回真

        使用示例如下:

[guest@centos7-front1 ~]$ ls
1.sh  attach  file
[guest@centos7-front1 ~]$ [ -e "/home/guest/file" ] && echo "True" || echo "False"
True
[guest@centos7-front1 ~]$ [ -d "/home/guest/file" ] && echo "True" || echo "False" 
False
[guest@centos7-front1 ~]$ [ -f "/home/guest/file" ] && echo "True" || echo "False" 
True
[guest@centos7-front1 ~]$ ls -al
total 28
drwx------  3 guest guest  144 Apr 17 16:51 .
drwxr-xr-x. 3 root  root    18 Mar 30 10:58 ..
-rwxr-xr-x  1 guest guest  171 Apr 17 16:51 1.sh
-rw-r--r--  1 root  root     1 Mar 30 13:21 attach
-rw-------  1 guest guest  416 Apr 10 17:05 .bash_history
-rw-r--r--  1 guest guest   18 Nov 20  2015 .bash_logout
-rw-r--r--  1 guest guest  193 Nov 20  2015 .bash_profile
-rw-r--r--  1 guest guest  231 Nov 20  2015 .bashrc
--w-------  1 guest guest    0 Apr 10 16:58 file
drwxr-xr-x  4 guest guest   37 Mar 19 18:42 .mozilla
-rw-------  1 guest guest 1013 Apr 17 16:51 .viminfo
[guest@centos7-front1 ~]$ 
[guest@centos7-front1 ~]$ [ -r "/home/guest/file" ] && echo "True" || echo "False" 
False
[guest@centos7-front1 ~]$ [ -w "/home/guest/file" ] && echo "True" || echo "False" 
True
[guest@centos7-front1 ~]$ [ -x "/home/guest/file" ] && echo "True" || echo "False" 
False
......
......
[guest@centos7-front1 ~]$ [ "/home/guest/.bash_history" -nt "/home/guest/.bash_logout" ] && echo "True" || echo " False"
True
[guest@centos7-front1 ~]$ [ "/home/guest/.bash_history" -ot "/home/guest/.bash_logout" ] && echo "True" || echo " False"  
 False

        关于整数的判断,使用的方式如下:

判断符 解释
-eq 判断前后两个整数是否相等,是则返回真
-ne 判断前后两个整数是否不相等,不相等则返回真
-gt 判断前一个整数是否大于后一个整数,是则返回真
-lt 判断前一个整数是否小于后一个整数,是则返回真
-ge 判断前一个整数是否大于等于后一个整数,是则返回真
-le 判断前一个整数是否小于等于后一个整数,是则返回真

        使用示例如下:

[root@centos7-front1 ~]# a=1 b=2 c=2
[root@centos7-front1 ~]# [ $a -eq $b ] && echo "True" || echo "False"
False
[root@centos7-front1 ~]# [ $a -ne $b ] && echo "True" || echo "False"  
True
[root@centos7-front1 ~]# [ $a -gt $b ] && echo "True" || echo "False"  
False
[root@centos7-front1 ~]# [ $a -lt $b ] && echo "True" || echo "False" 
True
[root@centos7-front1 ~]# [ $b -ge $c ] && echo "True" || echo "False"    
True
[root@centos7-front1 ~]# [ $b -le $c ] && echo "True" || echo "False"  
True

        关于字符串的判断,使用方式如下:

判断符 解释
-z 判断后面的字符串是否为空,是则返回真
-n 判断后面的字符串是否不为空,不为空则返回真
== 判断前后字符串是否相等,相等则返回真
!= 判断前后两个字符串是否不相等,不相等则返回真
> 前面字符串的ascii码是否大于后面字符串的ascii码,大于则返回真
< 前面字符串的ascii码是否小于后面字符串的ascii码,小于则返回真
=~ 左侧的字符串是否能够被右侧的pattern所匹配,是则返回真

        使用示例如下:

[root@centos7-front1 scripts]# cat execute.sh 
#!/bin/bash -x
ARG=$1
if [[ -f "$ARG" ]] && [[ "$ARG" =~ .sh$ ]]; then
        echo "ok"
else
        echo "fail"
fi
[root@centos7-front1 scripts]# bash execute.sh file 
fail
[root@centos7-front1 scripts]# bash execute.sh 1.sh 
ok
  • 流程控制 
    if语句控制流程,内容如下:
if [ 条件1 ];then
  expression
elif [ 条件2 ];then
  expression
  .....
else
  expression
fi

        多分支case语句控制流程,内容如下:

case $变量名 in
          "value1")
                expression
                ;;
          "value2")
               expression
               ;;
          .......
          *)
              expression
              ;; 
esac  


使用示例如下:
#!/bin/bash
read -t 30 -p "please input yes or no...." VAR
case $VAR in
        yes)
                echo "your input is yes."
        ;;
        no)
                echo "your input is no."
        ;;
        *)
                echo "your input is error..."
        ;;
esac

        for循环控制流程,内容如下:

形式1
for 变量  in  value1 value2 value3.....
do
      expression
done 

示例:
#!/bin/bash
cd /root/test/
ls *.tar.gz  >  ls.log
ls *.tgz    >>ls.log
for i in $(cat ls.log)
do
      tar -zxf $i &> /dev/null  #将执行中显示的信息丢到黑洞
done
rm -rf ls.log

形式2
for ((初始值;循环控制条件; 变量变化))
do
        expression
done

示例:
#!/bin/bash
#从1加到100
s=0;
for((i=1;i<=100;i=i+1))
do
     s=$(($s+$i))
done
echo "the sum is:$s"    

    while循环控制流程,只要条件为真,便一直执行下去。内容如下:

while [ 条件判断式 ]
do
   程序
done

示例:
#!/bin/bash
#从1加到100
i=1
s=0
while [ $i -le 100 ]
do
     s=$(($s+$i))
     i=$(($i+1))
done
echo "the sum is:$s"

    until循环控制流程,一直执行,直到条件为真为止。内容如下:

until [ 条件判断式 ]
do
   程序
done

示例:
i=1
s=0
until [ $i -ge 100 ]
do
     s=$(($s+$i))
     i=$(($i+1))
done
echo "the sum is:$s"

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

(0)
jiangche00jiangche00
上一篇 2017-04-18
下一篇 2017-04-18

相关推荐

  • Linux基础之shell脚本编程(三)

    1、写一个脚本,判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin);分别这两类用户的个数;通过字符串比较来实现;   1 #!/bin/bash   2 #author:BaoZhang   3 #  …

    Linux干货 2016-11-20
  • man和history及bashi的快捷键

    man:帮助命令     命令格式:man# cmd;使用时可以先使用whatis 查询所对应的man的章节,然后用对应的man章节来查询帮助;     info:本地帮助文档     官方文档,在线查询等等,如果是付费版系统的话可以使用S…

    Linux干货 2016-07-29
  • 第一周作业-01

    计算机组成    硬件:主要由5大部件组成,CPU包含运算器和控制器两大部件        CPU:运算器、控制器、寄存器、缓存        存储器:内存,RAM(Random Access Memory)    , Memory只支持平…

    Linux干货 2016-09-10
  • 推荐-LVM

    LVM LVM Linux应用 1.LVM简介 LVM:Logical Volume Manager,逻辑卷管理器。LVM利用Linux内核的device-mapper模块来实现存储系统的虚拟化(系统分区独立于底层硬件)。通过LVM,你可以实现存储空间的抽象化并在上面建立虚拟分区(virtual partitions),可以更简便地扩大和缩小分区,可以增删分…

    2016-04-11
  • 马哥教育网络班21期-第二周课程作业

    1、Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示。 cp即copy的简写,我们可以用它来复制一些文件即将,源文件的数据流复制到目的文件中。和下面要讲的rm,mv,一样都是一些非常基础的命令。关于这个命令,我们有个小窍门,那就是根据 ls file这个命令是否执行成功来判断file文件是否存在。 关于cp,我们有一些要点要注意: cp…

    Linux干货 2016-07-07

评论列表(1条)

  • renjin
    renjin 2017-04-21 10:00

    主要总结了shell编程的基础用法,内容总结的很详细,排版也很好,下次需要注意将代码再注释详细一些,尤其是在示例的代码中