ShellScript实用技巧[1]

工作中shell脚本的实用频率非常高,比如作为不同语言之间的胶水,或者是为了避免重复劳动而写的一次性工具。熟练掌握shell脚本的一些使用技巧,绝对是提高工作效率的利器!PS.本文中指的Shell都是Bash

shell的启动方式通过两种维度来划分,交互与非交互,登录与非登录。这里面其实比较复杂,不同的发行版本可能也不太一样,都可以另外写一篇来谈了。简单的说一般情况下你login了一台机器,在bash下就是交互登录启动,这个时候shell会先source /etc/profile,~/.bash_profile, ~/.bash_login, ~/.profile这3个文件(如果有的话),然后一般~/.bash_profile里面会source一把~/.bashrc。所以这个时候你执行一些脚本的话环境变量已经配置好了。但是如果是用crontab启动,就是非交互启动,这个时候shell只会source一边/etc/profile, 那么很多环境变量是没有设置的,所以通过crontab启动的脚本在开头最好都source一下~/.bash_profile或者~/.bashrc

---------------------------------------我是分割线------------------------------------

场景1

job1每天会执行一次,完成后会输出一个done文件到目录/home/minecraft/daily/yyyymmdd下,然后job1完成后执行job2

对于这个场景,我们可以每天在固定时间起一个crontab任务,任务执行一个shell脚本,该脚本每隔固定的时间去探查done文件是否存在,如存在则执行job2. 为了防止这个任务一直等待下去,一般会添加一个探查的次数限制。

另外一种思路是每天用crontab间隔一段时间就起一次任务来探查done文件,如存在则执行job2.这个思路存在一个问题,当我前一次探查到done后开始执行job2,后一次还是会来继续探查done文件,重复启动job2,产生错误。可以通过设置一个lock文件来终止后面的所有探查进程来保证job2的唯一性。在当前场景下思路1比较简洁有效。

思路1代码如下

 1 DATE=$(date +%Y%m%d)
 2 retry=60
 3 while :;
 4 do
 5     if [[ -e /home/minecraft/daily/${DATE}/done ]]; then
 6         break
 7     else
 8         ((retry--))
 9         sleep 10m
10     fi
11     if [[ ${retry} -le 0 ]]; then
12         exit 1
13     fi
14 done
15 
16 run job2
17  
18 exit 0

假如job1不是touch一个done文件,而是输出一个文件,那么我们就需要判断2点:1.文件是否存在;2.文件是否已经完成写入。第一点好判断,第二点的话可以每隔一段时间check一下文件大小,当2次check的大小不变,就可以认为文件已经写入完成了。查看文件大小可以用

1 size=$(wc -c < file)

 或者利用管道

1 size=$(cat file | wc -c)

又假设job1写入的是1天前的数据,那么可以利用

1 NDAYAGO=$(date "1 ady ago" "+%Y%m%d")

来获得日期字符串

TO BE CONTINUE...

原文地址:https://www.cnblogs.com/minecraft/p/3630925.html