如何避免shell指令碼被同時執行多次

2021-08-02 21:49:56 字數 1588 閱讀 7853

**:

比如說有乙個週期性(cron)備份mysql的指令碼,或者rsync指令碼,

如果出現意外,執行時間過長,

很有可能下乙個備份週期已經開始了,當前週期的指令碼卻還沒有執行完,

顯然我們都不願意看到這樣的情況發生。

其實只要對指令碼自身做一些改動,就可以避免它被重複執行。

#!/bin/bash

lock_name="/tmp/my.lock"

if [[ -e $lock_name ]] ; then

echo "re-entry, exiting"

exit 1

fi### placing lock file

touch $lock_name

echo -n "started..."

### 開始正常流程

### 正常流程結束

### removing lock

rm -f $lock_name

echo "done."

當指令碼開始執行時, 建立 /tmp/my.lock檔案,

這時如果再次執行此指令碼,發現存在my.lock,就退出,

指令碼執行結束時刪除這個檔案。

大多數情況下,這樣做都沒有什麼問題。

意外1) 如果同時執行二次此指令碼, 二個程序都會發現my.lock不存在,然後都可以繼續執行。

意外2) 如果指令碼在執行過程中意外退出, 沒有來得及刪除 my.lock檔案, 那麼就悲劇了。

修改如下:

#!/bin/bash

lock_name="/tmp/my.lock"

if ( set -o noclobber; echo "$$" > "$lock_name") 2> /dev/null; 

then

trap 'rm -f "$lock_name"; exit $?' int term exit

### 開始正常流程

### 正常流程結束

### removing lock

rm -f $lock_name

trap - int term exit

else

echo "failed to acquire lockfile: $lock_name." 

echo "held by $(cat $lock_name)"

exit 1

fiecho "done."

set -o noclobber 的意思:

if set, bash does not overwrite an existing file with the >, >&, and <> redirection operators.

這樣就能保證my.lock只能被乙個程序建立出來。比touch靠譜多了。

trap 可以捕獲各種訊號,然後做出處理:

int 用來處理 ctrl+c取消指令碼執行的情況。

term 用來處理 kill -term pid 的情況。

exit 不清楚

另外,對於 kill -9 無效。。

還記得n年前,在php群裡面,草人也問過這個問題,

我們給的答案是 ps aux|grep filename |wc -l ,哈哈,真2。

shell多個指令碼同時執行

1 編寫多程序實驗指令碼 demo.sh bin bash sub1.log sub2.log sub3.log function sub1 doecho date t sub1.log 注意date 和 號之間有空格。如 date m d date取 月 日 的命令列。sleep 1 done f...

避免同個後台作業同時執行

設定了乙個後台作業,頻率高,幾分鐘就執行一次,有時上一次作業還沒執行完,下一次又開始了,這時需要避免下一次的作業繼續執行下去 report ztest.parameters a type i default 200.data list like tbtcjmoni occurs 0 with hea...

如何編寫Linux定時執行shell指令碼任務

很多時候一些shell指令碼我們都希望伺服器可以自己定時的去執行,那麼以下作簡單講解 service crond start 啟動服務 service crond stop 關閉服務 service crond restart 重啟服務 service crond reload 重新載入配置 ser...