shell脚本可用性优化及功能实现最佳实践
计算脚本执行时间:
#!/bin/bash
starttime=`date +%s -d '2010-01-01 17:23:40'`
endtime=`date +%s -d '2010-01-01 15:01:47'`
time=`echo $(($endtime - $starttime)) | awk '{t=split("60 s 60 m 24 h 999 d",a);for(n=1;n<t;n+=2){if($1==0)break;s=$1%a[n]a[n+1]s;$1=int($1/a[n])}print s}'`
echo $time
在脚本输出中强化颜色提示(已经是加粗版的最大字体了):
#!/bin/bash red='\033[1;31m' green='\033[1;32m' end='\e[0m' echo -e "error${red}error${end}" echo -e "green${green}green${end}"
脚本进阶:使用函数对脚本功能进行结构化分离,使用case结构对函数进行功能划分并实现执行控制
1)case结构示例:
#!/bin/bash Title= oneSubtitle= twoSubtitle= threeSubtitle= fourSubtitle= fiveSubtitle= sixSubtitle= sevenSubtitle= echo cat <<EOF DATE : `date +%Y-%m-%d-%T` ========================================== $Title ========================================== ** 1)$oneSubtitle ** ** 2)$twoSubtitle ** ** 3)$threeSubtitle ** ** 4)$fourSubtitle ** ** 5)$fiveSubtitle ** ** 6)$sixSubtitle ** ** 7)$sevenSubtitle ** ========================================== EOF read -p "Please choose [1-7]:" num case $num in 1) function1 ;; 2) function2 ;; 3) function3 ;; 4) function4 ;; 5) function5 ;; 6) function6 ;; 7) function7 ;; *) clear ./$0 ;; esac
2)函数+case结构示例:
#!/bin/bash . /etc/rc.d/init.d/functions start(){ rsync --daemon if [ $? -eq 0 -a `ps -ef|grep -v grep|grep rsync|wc -l` -gt 0 ];then action "Starting Rsync:" /bin/true sleep 1 else action "Starting Rsync:" /bin/false sleep 1 fi } stop(){ pkill rsync;sleep 1;pkill rsync if [ `ps -ef|grep -v grep|grep "rsync --daemon"|wc -l` -lt 1 ];then action "Stopping Rsync: " /bin/true sleep 1 else action "Stopping Rsync:" /bin/true sleep 1 fi } case "$1" in start) start; ;; stop) stop; ;; restart|reload) stop; start; ;; *) echo $"Usage: $0 {start|stop|restart|reload}" ;; esac
为linux文件添加或覆盖多行内容:
cat >> /etc/security/limits.conf << EOF * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535 EOF cat > /etc/sysctl.conf << EOF net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 vm.swappiness = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.lo.arp_announce = 2 EOF
如代码所示,cat后>为覆盖,>>为追加
在执行脚本时添加一个动态的进度条来表示shell脚本正在运行,适用需要在前台执行并执行时间较长的脚本:
#!/bin/bash #将do_sth函数替换为脚本执行内容即可,在do_sth上面添加函数化的代码及source引用的函数,下面的不动,在do_sth函数中填入需要真正执行的代码,替换sleep 10即可 trap 'onCtrlC' INT function onCtrlC () { #捕获CTRL+C,当脚本被ctrl+c的形式终止时同时终止程序的后台进程 kill -9 ${do_sth_pid} ${progress_pid} echo echo 'Because input Ctrl+C is captured,script already stopped!' exit 1 } do_sth() { #运行的主程序 sleep 10 } progress() { #进度条程序 local main_pid=$1 local length=20 local ratio=1 while [ "$(ps -p ${main_pid} | wc -l)" -ne "1" ] ; do mark='>' progress_bar= for i in $(seq 1 "${length}"); do if [ "$i" -gt "${ratio}" ] ; then mark='-' fi progress_bar="${progress_bar}${mark}" done printf "Script is running: ${progress_bar}\r" ratio=$((ratio+1)) #ratio=`expr ${ratio} + 1` if [ "${ratio}" -gt "${length}" ] ; then ratio=1 fi sleep 0.1 done } do_sth & do_sth_pid=$(jobs -p | tail -1) progress "${do_sth_pid}" & progress_pid=$(jobs -p | tail -1) wait "${do_sth_pid}" printf "Script running done! \n"
将脚本中模块(或函数)以及重复代码的运行过程,以带百分比的进度条展示进度:
#!/bin/bash #将sleep 0.2替换为正常执行的代码即可,这部分进度条代码只能显示重复任务的运行进度 mark='' for ((ratio=0;${ratio}<=100;ratio+=5)) do sleep 0.2 printf "progress:[%-40s]%d%%\r" "${mark}" "${ratio}" mark="##${mark}" done echo
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通