Shell 脚本编程

环境

  • CentOS 7.3
  • bash
  • IntelliJ IDEA 2017.1 + Vim
  • Xshell 5

基础

  • shell 本质是一个命令解析器,我们这里讲的是 shell 脚本的编写/编程。
  • shell 的软件有:sh、bash、zsh、csh、tcsh、ksh 等,Linux 发行版一般是 bash,我个人常用 bash 和 zsh
  • 查看 bash 版本号:bash --version,CentOS 7.3 是 4.2.46
  • shell 脚本文件后缀:sh
  • shell 脚本开头语言标识。文件开头是:#!/bin/sh#!/bin/bash(优先使用这个)(其实也可以不加,因为 Linux 默认就是 bash,只是为了合理,一般都要加),主要是告诉哪个解析器来执行脚本。如果该语句写在非第一行,那就是当做注释使用。
    • 其中 /bin/sh 是 bash 的软链接,所以以上两种写法都可以。(证明:ls -l /bin/sh
    • 但是业界上,sh 和 bash 其实是有历史区别的。
    • sh 即 Bourne shell,POSIX(Portable Operating System Interface)标准的 shell 解释器,它的二进制文件路径通常是 /bin/sh,由 Bell Labs 开发。
    • bash 是 Bourne shell 的替代品,属 GNU Project,二进制文件路径通常是 /bin/bash。
    • Mac OS 上 /bin/sh 和 /bin/bash 是两个不同的文件
  • 换行符(line separator):IntelliJ IDEA 下编写脚本的时候一定要注意后下角的 LF 还是 CRLF,LF 才是 Linux 的要求。
  • 执行脚本命令:bash /opt/test.sh(推荐),还有:. /opt/test.shsource /opt/test.sh
    • 用 source 或是 点开头 的优点是:后面执行的脚本可以读取 source 或 点 执行脚本中的变量内容,但是这个读取也只是基于一个 shell 状态下,如果是另外开的 shell 是没有用的。
  • 注释:用 # 号开头,只有单行注释,没有多行注释的用法。
  • 如果脚本是用于 Crontab 定时任务,则定义在 /etc/profile 中的环境变量是无法使用的,需要重新定义。
  • 给脚本赋上执行权限:chmod +x gitnavi.sh

变量

变量概念

  • 敲黑板,重点:等于号,左右两边不要有空格,这个跟一般语言的语法很有冲突感。
  • 查看系统的环境变量列表:envset
  • 用户环境变量设置位置:vim ~/.bash_profile
  • 全局环境变量:vim /etc/profile,或者在目录:/etc/profile.d/ 下自己写一个 sh 文件,然后设置一下变量
  • 变量命名只能使用字母,下划线和数字,并且不能以数字开头
  • 环境变量要建议设置为全大写
  • 环境变量需要 export 导出,完整设置,比如下面设置 JDK:
  1. JAVA_HOME=/usr/program/jdk1.8.0_121
  2. export JAVA_HOME
  • 普通字符串变量:gitnavi_url="gitnavi.com",虽然也可以用单引号或是不使用任何符号,但是不推荐。
    • 使用双引号可以在变量中使用其他变量,双引号内容中有双引号,再加个转移斜杠即可,如下:
    • str="Hello, \"${gitnavi_url}\"! \n"
  • 数值型变量:gitnavi_age=3
  • 路径型变量:gitnavi_patch=/com/gitnavi/youmeek
  • 删除变量:unset gitnavi_url
  • 使用变量:
    • echo $gitnavi_url,不推荐这种
    • echo ${gitnavi_url},推荐这种
  • 拼接字符串:
  1. gitnavi_url="gitnavi.com"
  2. gitnavi_say="hello, ${gitnavi_url} !"
  3. echo ${gitnavi_say}
  • 获取字符串长度,多加一个 # 号:
  1. gitnavi_url="gitnavi.com"
  2. echo ${#gitnavi_url}
  • 截取字符串(下标是从 0 开始):
  1. gitnavi_url="gitnavi.com"
  2. echo ${gitnavi_url:1:4}
  • 查找子字符串出现的最开始下标位置(下标开始是 0,所以下面结果是:2):
  1. gitnavi_url="gitnavi.com"
  2. echo `expr index "${gitnavi_url}" navi`

控制流

条件语句

  • if
  1. if [ condition ]
  2. then
  3. command
  4. fi
  • if - else
  1. if [ condition ]
  2. then
  3. command
  4. else
  5. command
  6. fi
  • if - else if - else if - else
  1. if [ condition1 ]
  2. then
  3. command1
  4. elif [ condition2 ]
  5. command2
  6. elif [ condition3 ]
  7. command3
  8. else
  9. commandN
  10. fi

case 语句(switch - case)

  • 条件可以是一个变量或是常数
  1. case "${gitnavi_url}" in
  2. "${condition1}" )
  3. command1
  4. ;;
  5. "helloworld" )
  6. command2
  7. ;;
  8. * )
  9. command3 # 这里相当于 case 语句的 default
  10. ;;
  11. esac

循环语句

  • for 语句
  • 列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。
  1. for 变量 in 列表
  2. do
  3. command1
  4. command2
  5. ...
  6. commandN
  7. done
  • while 语句
  1. while [ condition ]
  2. do
  3. command
  4. done

资料