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 bash
while getopts ":h:p:" optname;do
case "$optname" in
"h")
host_ip=$OPTARG
;;
"p")
host_port=$OPTARG
;;
"?" )
echo "不知道此选项"
;;
esac
done
echo "IP是${host_ip},端口是${host_port}"
#执行效果如下
[root@mysql nginx]# sh test.sh -h 192.168.20.2 -p 3306
IP是192.168.20.2,端口是3306
[root@mysql nginx]# sh test.sh -p 22 -h 192.168.20.3
IP是192.168.20.3,端口是22
h2标记
$ cat a.sh # 脚本内容如下
#!/usr/bin/env bash
item=1 # 定义初始值
h2() {
printf "\n${underline}${bold}${white}%s${reset}\n" "$@"
}
# 定义h2函数,以便下面调用
h2 "[Step $item]: 第一阶段..."; let item+=1
echo one
h2 "[Step $item]: 第二阶段..."; let item+=1
echo two
h2 "[Step $item]: 第三阶段..."; let item+=1
echo three
执行效果如下:
使用数组
#!/usr/bin/env bash
set -e
yum_list=(
gcc
gcc-c++
autoconf
automake
pcre
pcre-devel
openssl
openssl-devel
patch
net-tools
)
for i in ${yum_list[@]}
do
yum 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
<< COMMENT
Author : 吕建钊
Date : 2020-07-31
Email : lvjianzhao@aspirecn.com
COMMENT
set -e
item=1
h2() {
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 ]];then
echo -e "\033[31m
此脚本必须使用 root 执行
当前用户为 ${USER}
正在退出脚本...
\033[0m"
sleep 1 && exit 1
fi
h2 "[Step $item]: 第二阶段..."; let item+=1
echo two
h2 "[Step $item]: 第三阶段..."; let item+=1
echo three
......................
echo -e "\033[33m
结束提示语!!!
\033[0m"
tr指令
free -h | grep -i mem | tr -s " "| cut -d " " -f7
1.5G
# tr -s : 将多个连续的字符合并为一个。
控制分隔符—— IFS
shell中默认以空格为分隔符,有时需要改变它,示例如下:
$ OLD_IFS=${IFS} # 先备份当前分隔符
$ IFS=":" # 更改默认分隔符为冒号
$ read -p "请输入3个数据: " x y z
请输入3个数据: a:b:c
[12::root@lv::~]# >>$ echo $x
a
[13::root@lv::~]# >>$ echo $y
b
[14::root@lv::~]# >>$ echo $z
c
中断与退出控制
- 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 bash
starttime=$(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"
do
case $item in
"CPU")
uptime;;
"IP")
ip a s;;
"MEM")
free -h;;
"exit")
exit;;
*)
echo "error";;
esac
done
使用while实现:
function install_menu() {
while true
do
cd ${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" var
echo ""
case $var in
1)
echo -e "\e[1;33mStart Deployment Nginx \e[0m"
tar zxf install_nginx-1.18.0.tgz && cd nginx_install
chmod +x install_nginx.sh && ./install_nginx.sh
echo -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.5
chmod +x install.sh && ./install.sh
echo -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.31
chmod +x install.sh && ./install.sh
echo -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"
;;
esac
done
}
clear
install_menu