Linux

Shell脚本编写

勤劳的小蜜蜂 · 6月25日 · 2020年 · ·

本文将记录从零开始学习shell编程过程中,值得记录的点和代码段

最近一直都在和 linux 打交道,大佬们的一键脚本让我深深感受到了 linux 的魅力。所以呢,也想着有朝一日也能编写出各种脚本供大家使用。

设置文字颜色

red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

echo "${green}这是绿色${plain}"
echo "${yellow}这是黄色${plain}"
echo "${red}这是红色${plain}"

检查是否是root用户

[[ $EUID -ne 0 ]] && echo -e "${red}错误: ${plain} 必须使用root用户运行此脚本!\n" && exit 1

检查linux发行版本

# check os
if [[ -f /etc/redhat-release ]]; then
    release="centos"
elif cat /etc/issue | grep -Eqi "debian"; then
    release="debian"
elif cat /etc/issue | grep -Eqi "ubuntu"; then
    release="ubuntu"
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
    release="centos"
elif cat /proc/version | grep -Eqi "debian"; then
    release="debian"
elif cat /proc/version | grep -Eqi "ubuntu"; then
    release="ubuntu"
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
    release="centos"
else
    echo -e "${red}未检测到系统版本${plain}\n" && exit 1
fi

发行版本号

if [[ -f /etc/os-release ]]; then
    os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release)
fi
if [[ -z "$os_version" && -f /etc/lsb-release ]]; then
    os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release)
fi

if [[ x"${release}" == x"centos" ]]; then
    if [[ ${os_version} -le 6 ]]; then
        echo -e "${red}请使用 CentOS 7 或更高版本的系统!${plain}\n" && exit 1
    fi
elif [[ x"${release}" == x"ubuntu" ]]; then
    if [[ ${os_version} -lt 16 ]]; then
        echo -e "${red}请使用 Ubuntu 16 或更高版本的系统!${plain}\n" && exit 1
    fi
elif [[ x"${release}" == x"debian" ]]; then
    if [[ ${os_version} -lt 8 ]]; then
        echo -e "${red}请使用 Debian 8 或更高版本的系统!${plain}\n" && exit 1
    fi
fi

$#、$0、$1、$@、$$、$? 含义

  • $# 是传给脚本的参数个数
  • $0 是脚本本身的名字
  • $1 是传递给该shell脚本的第一个参数,$2、$3…以此类推
  • $@ 是传给脚本的所有参数的列表
  • $$ 是脚本运行的当前进程ID号
  • $? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误(经常用来判断上一句执行结果)

条件判断

commands 的值需要是布尔类型。

ifthen写在同一行时,需要分号分隔。分号是 Bash 的命令分隔符。它们也可以写成两行,这时不需要分号。

if test

if 通常用 test 作为判断条件,test 也能单独使用,返回值是 boolean 类型

# 写法一
if test expression

# 写法二
if [ expression ]

# 写法三
if [[ expression ]]

1、上面三种形式等价

2、写法三支持正则表达式

3、[] 与expression 必须有空格

4、test 命令内部的 ><,必须用引号引起来(或者是用反斜杠转义)。否则,它们会被 shell 解释为重定向操作符。

test 支持文件判断、整数判断、正则判断、算术判断、命令逻辑运算,具体参考文章https://wangdoc.com/bash/condition.html#%E5%88%A4%E6%96%AD%E8%A1%A8%E8%BE%BE%E5%BC%8F

为输入设置默认值

echo && read -p "请输入选择 [0-3](默认 tcp): " num
if [ -z "${num}" ];then
   num=1
fi

-z 后面的参数为空,则返回 true

将多行命令写入文件

cat > docker-compose.yml << EOF
version: "3"
services:
  mysql:
    image: mysql
    restart: always
    ports:
      - "${ports}:${ports}"
    logging:
      options:
        max-size: "10m"
        max-file: "3"
EOF

1、cat > 为覆盖写入

2、cat >> 为追加写入

3、EOF 为标识符,任意字符均可

条件选择

echo -e "
  ${green}请选择面板 type 类型${plain}
  ${green}0.${plain} 退出脚本
————————————————

  ${green}1.${plain} 安装
  ${green}2.${plain} 卸载

————————————————
 "
    echo && read -p "请输入选择 [0-2]: " num
    case "${num}" in
        0) exit 0
        ;;
        1) install
        ;;
        2) uninstall
        ;;
        *) echo -e "${red}请输入正确的数字 [0-2]${plain}"
        ;;
    esac

1、echo -e 会执行 ${} 命令,否则原样输出

2、echo -n 为不换行,一般用于同行接受用户输入

按任意键继续 或者 CTRL+C 取消执行

echo "按任意键继续 或者 CTRL+C 取消执行"; read