shell 使用总结

ubuntu 下部署服务的时候,经常出现大量反复的操作,而且还容易出错,所有刚好可以通过 shell 脚本的形式 将这个部分完美替代了
在写脚本过程中,对自己使用到一些知识进行了简单的总结

语法

变量

  • 定义变量时,变量名不加 $;
    • 变量名和等号之间不能有空格
    • 命名只能是因为字母数字和下划线,首字符不能是数字开头
    • 不能使用 bash 里的关键字
  • 使用变量时,只要在变量名前加 $ 修饰

常用数据类型: 字符串 和 数字

关键字

关键字 描述
&& && 前的命令执行成功了就继续执行后面的命令
`
; 不论 ; 前的命令执行成功与否都去执行后面的命令

输出打印

  • echo “字符串” 或者 echo 字符串
  • echo -e “\n” 等等支持转义
  • echo -n “…” 打印输出后光标不换行 类似与 echo -e “\c”

脚本输入参数

params

获取输入参数语法

参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。
如”$*“用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与\$*相同,但是使用时加引号,并在引号中返回每个参数。
如”$@“用「”」括起来的情况、以”$1” “$2” … “$n” 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

函数

函数写法, 支持参数的输入和返回值,返回值通过 $? 获取, []部分可省略

[function] 函数名[()] 
{
    dosomething

    [return 0]    
}

可以结合这个下面的 demo 简单理解一下

function

判断

数值判断

参数 说明
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真

字符串判断

参数 说明
= 等于则为真
!= 不相等则为真
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真

流程

if 判断写法

if condition1
then
    command1
elif condition2
    command2
else
    command3
if

for 循环写法

for arg in "$@"
do
    echo $arg
done

while, until 语句

while condition
do
    command
done

until condition
do
    command
done

循环都支持 breakcontinue 跳出循环和跳出当前循环

case 语句

case 值 in
模式1)
    command1
    ;;
模式2)
    command2
    ;;
*)
    command2
    ;;
esac

文本分析工具 awk

服务是以 docker 形式部署,在实际部署过程中,因为部分服务没有更新,所有需要从 docker 中查询出指定的服务当前的版本和运行状态 docker ps | grep servicename 这个获取的一行数据,需要从这一行中按照一定的规则解析出服务的版本和一些其他信息,所有 awk 作为一款非常强大的文本分析工具,就能体现它的作用了

echo $(docker ps | grep servicename | awk '{print $1}' | awk -F ':' '{print $1}')

简单写一下常用的用法

  • awk 读入一行数据,并且默认按照空格分隔成若干个字符串, 通过 '{print $1}',获取第几个字符串
  • -F ':' 将读入的数据,以 : 分割

详细用法可以查看下面这篇博客,介绍的很详细

awk基本用法
官方文档

读取其他的文件

例如用一个文件 version.properties 存储所有部署服务的版本信息, deploy.sh 部署脚本通过读取 version.properties 对应服务的版本信息以及一些配置信息从而部署

以下图为例

source

常见问题

source: not found

问题现象: 例如 a.sh

#!/bin/bash

soucre ./a.properties
echo ${key}

在执行 sh ./a.sh 报错, 报错内容为 soucre: not found

查看 sh 的软链接 ll /bin/sh 会发现 `sh` 链接的对象是 dash, 所以针对这个问题存在三个解决方案

第一种 使用 bash 启动

例如 bash ./a.sh

第二种 切换 shbash

Ubuntu切换默认sh为bash或者dash 参考这篇博客,很详细,也介绍了 bashdash 之间的区别

第三种 “./*.sh” 执行

*.sh 文件开头申明文件类型 #!/bin/bash, 通过修改文件的可运行权限后, 直接 ./*.sh 执行

总结:不仅仅如此,bashdash 语法上存在一些差异,在确定自己语法没有问题的时候,有的时候可能就是因为这个问题,最好都是用 bash ./*.sh 执行

bash:权限不够

直接执行 ./a.sh 报错内容为 bash: ./a.sh: 权限不够

解决方案:

  • chmod 777 ./a.sh
  • chmod -x ./a.sh

;;、&、&&之间的区别

;;:
command1;command2

–不管command1命令是否执行成功,command2命令都执行。

&:
command1&command2

–command1命令和command2命令同时执行

&&:
command1&&command2

–只在command1命令执行后,才执行command2命令。