分享

防止shell脚本重复执行

 goodwangLib 2014-04-11

利用锁机制,让一个特定的shell脚本,每次只能运行一个实例。具体来说,获得锁的脚本实例,能够继续往下执行临界区代码;没有获得锁的实例,则只能等待。

例如,要求脚本只能顺序访问某个资源,例如磁盘文件等,就可以参考下面的实现。


  1. #!/bin/bash  
  2. #  
  3. # file locking using bash.  
  4. # ver 0.1.6  
  5. #  
  6. # author : malundao ( malundao@sina.com )  
  7. # date   : 2011-08-31     
  8. # ref    : http://unix./Newsgroups/comp.unix.shell/2005-09/0472.html  
  9. #  
  10. # note:  
  11. #   shflock_cleanhook() is a user defined function to clean up user-specific sth.  
  12. #  
  13.   
  14.   
  15. # /path/to/lock/. note; directory, not a file.  
  16. # should be modified   
  17. LOCKPATH="/tmp"  
  18.   
  19.   
  20. cleanup() {  
  21.         shflock_cleanhook  
  22.   
  23.   
  24.         cd $LOCKPATH  
  25.         [ -e lock.pid ] || exit  
  26.   
  27.   
  28.         read pid >/dev/null 2>&1 <lock.pid  
  29.         if [ -n "$pid" ]; then  
  30.             if [ "$pid" == "$$" ]; then  
  31.                 rm -f lock.$pid  
  32.                 rm -f lock.pid  
  33.                 exit   
  34.             fi    
  35.         fi    
  36.         exit  
  37. }  
  38.   
  39.   
  40. #  trap EXIT ?   
  41. trap 'cleanup' HUP INT TERM  
  42.   
  43.   
  44. getlock() {  
  45.         oldpath=`pwd`  
  46.         cd $LOCKPATH  
  47.         while  
  48.                 echo $$ > lock.$$  
  49.                 [ -e lock.pid ]   
  50.         do  
  51.                 rm lock.$$  
  52.                 read pid >/dev/null 2>&1 <lock.pid  
  53.                 if [ -n "$pid" ]; then  
  54.                         if [ -e /proc/$pid ]; then  
  55.                                 cd $oldpath  
  56.                                 return 1 # Lock is taken by others  
  57.                         else  
  58.                                 #unsafe: rm -f lock.$pid  
  59.                                 echo WARN: please delete stale lock.pid by HAND.  
  60.                                 return 2  
  61.                         fi  
  62.                 else  
  63.                         # sleep some seconds,then back to 'while' loop  
  64.                         # 11 is a prime number, $$ as a random.    
  65.                         echo sleep $(( $$ % 11 ))  
  66.                         sleep $(( $$ % 11 ))  
  67.                 fi  
  68.         done  
  69.         # 'ln -s' is an atom op.   
  70.         ln -s lock.$$ lock.pid >/dev/null 2>&1  
  71.         if [ $? -eq 0 ]; then  
  72.                 cd $oldpath  
  73.                 return 0 # We got the lock  
  74.         else  
  75.                 [ -e lock.pid ] || echo WARN: please delete hanging lock.pid by HAND.  
  76.                 cd $oldpath  
  77.                 return 3 # Lock is probably taken by others.  
  78.         fi  
  79. }  
  80.   
  81.   
  82. putlock () {  
  83.     oldpath=`pwd`  
  84.     cd $LOCKPATH && rm -f lock.$$ lock.pid  
  85.     cd $oldpath  
  86. }  
  87.   
  88.   
  89. ## test   
  90. shflock_cleanhook() {  
  91.     echo i\'m a hook.  
  92. }  
  93. while true; do  
  94.     while ! getlock; do  
  95.         #echo wait a second...  
  96.         sleep 1  
  97.     done  
  98.   
  99.   
  100.     echo \[$$\] `date` ,now hold lock for 3 seconds...  
  101.     sleep 3  
  102.     #echo putlock  
  103.     putlock  
  104.     sleep 1 # yield  
  105. done  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多