-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bash-flock-wrapper.sh
executable file
·118 lines (96 loc) · 5.31 KB
/
bash-flock-wrapper.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env bash
# -------------------------------------------------------------------------------- #
# Description #
# -------------------------------------------------------------------------------- #
# A bash script skeleton for creating scripts that can only run one instances at #
# any given time by using flock. Ideal for cron based tasks that might overlap #
# due to timing constrants. #
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Actual Script #
# -------------------------------------------------------------------------------- #
# This is the 'main' function for the actual script that you want to run inside #
# the lock. This can call other functions, or have arguments passed to it etc. #
# -------------------------------------------------------------------------------- #
function actual_script()
{
echo "I am Locked - Sleep time"
sleep 3
echo "Now I Unlock"
}
# -------------------------------------------------------------------------------- #
# Core Internals #
# -------------------------------------------------------------------------------- #
# All of the code below form the core internals of the flock wrapper. No changes #
# should need to be made to this code and all changes / additions should be made #
# to the actual_script function above. #
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Global Variables #
# -------------------------------------------------------------------------------- #
# The following global variables are used simple to make the header look nice. #
# -------------------------------------------------------------------------------- #
# shellcheck disable=SC2155
readonly PROGNAME=$(basename "$0")
readonly LOCKFILE_DIR=/tmp
readonly LOCK_FD=200
# -------------------------------------------------------------------------------- #
# Lock #
# -------------------------------------------------------------------------------- #
# This function handle the creation and validation of existing lock files. #
# -------------------------------------------------------------------------------- #
function lock()
{
local prefix=$1
local fd=${2:-$LOCK_FD}
lock_file=$LOCKFILE_DIR/$prefix.lock
command=$(command -v "flock")
if [[ -z $command ]]; then # Flock is not installed - work around
if ( set -o noclobber; echo "$$" > "${lock_file}") 2> /dev/null;
then
# shellcheck disable=SC2064
trap 'rm -f "${lock_file}"; exit $?' INT TERM EXIT
return 0
else
return 1
fi
else
eval "exec $fd > ${lock_file}"
flock -n "${fd}" && return 0 || return 1
fi
}
# -------------------------------------------------------------------------------- #
# eexit #
# -------------------------------------------------------------------------------- #
# A simple exit wrapper which will output the given error before exiting. #
# -------------------------------------------------------------------------------- #
function eexit()
{
local message="${1:-}"
if [[ -n "${message}" ]]; then
echo "${message}"
fi
exit 1
}
# -------------------------------------------------------------------------------- #
# Wrapper #
# -------------------------------------------------------------------------------- #
# The main wrapper function which handles the locking and calling of main #
# processing function. #
# -------------------------------------------------------------------------------- #
function wrapper()
{
lock "${PROGNAME}" || eexit "Only one instance of ${PROGNAME} can run at one time."
actual_script
}
# -------------------------------------------------------------------------------- #
# Main() #
# -------------------------------------------------------------------------------- #
# This is the actual 'script' and the functions/sub routines are called in order. #
# -------------------------------------------------------------------------------- #
wrapper
# -------------------------------------------------------------------------------- #
# End of Script #
# -------------------------------------------------------------------------------- #
# This is the end - nothing more to see here. #
# -------------------------------------------------------------------------------- #