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 11:03
下一篇 2017-04-18 14:07

相关推荐

  • HA cluster应用—CoroSync+Pacemaker

    HA cluster应用——CoroSync v2 (quorum system)+Pacemaker (standalone daemon)+ crmsh/pcsh corosync简述: Corosync是OpenAIS发展到Wilson版本后衍生出来的开放性集群引擎工程。可以说Corosync是OpenAIS工程的一部分。OpenAIS从openais…

    2016-11-27
  • bash的基础特性[更新中]

    2、bash的工作特性之命令执行状态返回值和命令行展开所涉及的内容及其示例演示。
    3、请使用命令行展开功能来完成以下练习:
    (1)、创建/tmp目录下的:a_c, a_d, b_c, b_d
    (2)、创建/tmp/mylinux目录下的:
    mylinux/
    ├── bin
    ├── boot
    │   └── grub
    ├── dev
    ├── etc
    │   ├── rc.d
    │   │   └── init.d
    │   └── sysconfig
    │   └── network-scripts
    ├── lib
    │   └── modules
    ├── lib64
    ├── proc
    ├── sbin
    ├── sys
    ├── tmp
    ├── usr
    │   └── local
    │   ├── bin
    │   └── sbin
    └── var
    ├── lock
    ├── log
    └── run
    5、如何定义一个命令的别名,如何在命令中引用另一个命令的执行结果?
    6、显示/var目录下所有以l开头,以一个小写字母结尾,且中间至少出现一位数字(可以有其它字符)的文件或目录。
    7、显示/etc目录下,以任意一个数字开头,且以非数字结尾的文件或目录。
    8、显示/etc目录下,以非字母开头,后面跟了一个字母以及其它任意长度任意字符的文件或目录。
    9、在/tmp目录下创建以tfile开头,后跟当前日期和时间的文件,文件名形如:tfile-2016-05-27-09-32-22。
    10、复制/etc目录下所有以p开头,以非数字结尾的文件或目录到/tmp/mytest1目录中。
    11、复制/etc目录下所有以.d结尾的文件或目录至/tmp/mytest2目录中。
    12、复制/etc/目录下所有以l或m或n开头,以.conf结尾的文件至/tmp/mytest3目录中。

    2018-03-17
  • SUID_SGID_Sticky简单总结

    参考: http://blog.chinaunix.net/uid-25314474-id-3313109.html —————————————权限——&#82…

    Linux干货 2015-09-14
  • N26-博客作业-week7

    1、创建一个10G分区,并格式为ext4文件系统;      (1) 要求其block大小为2048, 预留空间百分比为2, 卷标为MYDATA, 默认挂载属性包含acl;     ~]# fdisk /dev/sda Welcome to fdisk (util-li…

    Linux干货 2017-03-19
  • rsyslog日志记录服务器

    rsyslog日志记录服务器 部分思路总结摘自网络http://xuding.blog.51cto.com/4890434/1737947 一、syslog系统 1.syslog:系统日志服务,统一日志管理 支持C/S架构:可通过UDP或TCP协议提供日志记录服务;实现集中收集日志功能 (1)日志、事件 历史事件日志,保存系统上过去一段时间的发生的事件 事件…

    Linux干货 2016-11-07
  • nginx学习

    nginx    nginx的核心配置项:        Core functionality:核心配置,Glob配置段            daemon:是否开启为守护进程        &nbs…

    2017-05-08

评论列表(1条)

  • renjin
    renjin 2017-04-21 10:00

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