title: shell技巧 #标题tags: shell #标签
categories: shell # 分类
date: 2021-02-09
shell变量状态赋值
- ${VAR:-string} 如果VAR变量为空则返回string
- ${VAR:+string} 如果VAR变量不为空则返回string
- ${VAR:=string} 如果VAR变量为空则重新赋值VAR变量值为string
- ${VAR:?string} 如果VAR变量为空则将string输出到stderr
getopts使用
[root@mysql nginx]# vim test.sh #脚本内容如下#!/usr/bin/env bashwhile getopts ":h:p:" optname;docase "$optname" in"h")host_ip=$OPTARG;;"p")host_port=$OPTARG;;"?" )echo "不知道此选项";;esacdoneecho "IP是${host_ip},端口是${host_port}"#执行效果如下[root@mysql nginx]# sh test.sh -h 192.168.20.2 -p 3306IP是192.168.20.2,端口是3306[root@mysql nginx]# sh test.sh -p 22 -h 192.168.20.3IP是192.168.20.3,端口是22
h2标记
$ cat a.sh # 脚本内容如下#!/usr/bin/env bashitem=1 # 定义初始值h2() {printf "\n${underline}${bold}${white}%s${reset}\n" "$@"}# 定义h2函数,以便下面调用h2 "[Step $item]: 第一阶段..."; let item+=1echo oneh2 "[Step $item]: 第二阶段..."; let item+=1echo twoh2 "[Step $item]: 第三阶段..."; let item+=1echo three
执行效果如下:

使用数组
#!/usr/bin/env bashset -eyum_list=(gccgcc-c++autoconfautomakepcrepcre-developensslopenssl-develpatchnet-tools)for i in ${yum_list[@]}doyum install --downloadonly --downloaddir=/tmp/rpm/${i}/ ${i}done# @表示调用数组中的所有元素# 若要调用数组中的某个元素,使用以下指令:echo ${yum_list[-3]}echo ${yum_list[3]}# 注:正向是从 0 开始,倒向是从-1开始。
获取当前脚本路径
cur_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
shell脚本固定格式
#!/usr/bin/env bash<< COMMENTAuthor : 吕建钊Date : 2020-07-31Email : lvjianzhao@aspirecn.comCOMMENTset -eitem=1h2() {printf "\n${underline}${bold}${white}%s${reset}\n" "$@"}cur_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )cur_date=$(date +%F_%H%M)cd ${cur_dir}h2 "[Step $item]: 第一阶段..."; let item+=1# 依据实际情况来定,是否需要root执行此脚本if [[ ${USER} != root ]];thenecho -e "\033[31m此脚本必须使用 root 执行当前用户为 ${USER}正在退出脚本...\033[0m"sleep 1 && exit 1fih2 "[Step $item]: 第二阶段..."; let item+=1echo twoh2 "[Step $item]: 第三阶段..."; let item+=1echo three......................echo -e "\033[33m结束提示语!!!\033[0m"
tr指令
free -h | grep -i mem | tr -s " "| cut -d " " -f71.5G# tr -s : 将多个连续的字符合并为一个。
控制分隔符—— IFS
shell中默认以空格为分隔符,有时需要改变它,示例如下:
$ OLD_IFS=${IFS} # 先备份当前分隔符$ IFS=":" # 更改默认分隔符为冒号$ read -p "请输入3个数据: " x y z请输入3个数据: a:b:c[12::root@lv::~]# >>$ echo $xa[13::root@lv::~]# >>$ echo $yb[14::root@lv::~]# >>$ echo $zc
中断与退出控制
- continue:用于结束此次循环,也可以continue后面加 数字,指定跳出几次循环(默认为1)。
- break:用于结束整个循环体,后面可以指定数字,来控制跳出几层循环(默认为1)。
- exit:用于退出整个脚本,后面可以追加数字,但这个数字定义的是退出状态码。
文件属性判断与比较
| 操作符 | 功能 |
|---|---|
| -e file | 判断文件或目录是否存在,存在返回true,反之为false |
| -f file | 判断存在且为普通文件 |
| -d file | 判断存在且为目录 |
| -b file | 判断存在且为块设备文件,如磁盘、U盘等 |
| -c file | 判断存在且为字符设备文件,如键盘、鼠标等 |
| -L file | 判断存在且为软链接文件 |
| -r file | 判断存在且当前用户有可读权限 |
| -w file | 判断存在且当前用户有可写权限 |
| -x file | 判断存在且当前用户有可执行权限 |
| -s file | 判断文件是否存在并且文件大小非空 |
| file1 -ef file2 | 两个文件使用相同设备、相同inode编号,则返回true,否则返回false |
| file1 -nt file2 | file1 比file2 更新时返回true,或者file1存在而file2不存在则返回真 |
| file1 -ot file2 | file1 比file2 更旧时返回true,或者file2存在而file1不存在则返回真 |
记录脚本执行时长
#!/usr/bin/env bashstarttime=$(date +'%Y-%m-%d %H:%M:%S')# .........命令体endtime=$(date +'%Y-%m-%d %H:%M:%S')start_seconds=$(date --date="$starttime" +%s);end_seconds=$(date --date="$endtime" +%s);echo "${log_path} 目录下的日志已排查完成,共耗时"$((end_seconds-start_seconds))"s" > /tmp/log_delete.log
创建菜单
使用select实现:
#!/usr/bin/env bash# Description: 根据用户选择的菜单实现对应的功能echo "请根据提示选择您的操作: "select item in "CPU" "IP" "MEM" "exit"docase $item in"CPU")uptime;;"IP")ip a s;;"MEM")free -h;;"exit")exit;;*)echo "error";;esacdone
使用while实现:
function install_menu() {while truedocd ${cur_dir}echo ""echo -e "\e[1;36m [ Deployment Menu ] \e[0m"echo -e "\e[1;34m ------------------------------ \e[0m"echo -e "\e[1;32m 1) Deployment Nginx \e[0m"echo ""echo -e "\e[1;34m 2) Deployment Redis \e[0m"echo ""echo -e "\e[1;33m 3) Deployment MySQL \e[0m"echo ""echo -e "\e[1;35m q) Quit Deployment Task \e[0m"echo -e "\e[1;34m ------------------------------ \e[0m"echo ""read -p "$view_name" varecho ""case $var in1)echo -e "\e[1;33mStart Deployment Nginx \e[0m"tar zxf install_nginx-1.18.0.tgz && cd nginx_installchmod +x install_nginx.sh && ./install_nginx.shecho -e "\e[1;32mDeployment Complete Nginx \e[0m";;2)echo -e "\e[1;33mStart Deployment Redis \e[0m"tar zxf install_redis-5.0.5.tgz && cd install_redis-5.0.5chmod +x install.sh && ./install.shecho -e "\e[1;32mDeployment Complete Redis \e[0m";;3)echo -e "\e[1;33mStart Deployment Mysql \e[0m"tar zxf install_mysql-5.7.31.tgz && cd install_mysql-5.7.31chmod +x install.sh && ./install.shecho -e "\e[1;32mDeployment Complete Mysql \e[0m";;q )echo -e "\e[1;32m ------------------------ \e[0m"echo -e "\e[1;32m | Quit Deployment Task | \e[0m"echo -e "\e[1;32m ------------------------ \e[0m"echo ""exit 0;;* )echo -e "\e[1;31m ********************************** \e[0m"echo -e "\e[1;31m * Input Error,Please try again * \e[0m"echo -e "\e[1;31m ********************************** \e[0m";;esacdone}clearinstall_menu
