Skip to content

Instantly share code, notes, and snippets.

@undying
Created May 5, 2025 11:48
Show Gist options
  • Save undying/d68fc7f87ca864db4da2cfee2e4d0ede to your computer and use it in GitHub Desktop.
Save undying/d68fc7f87ca864db4da2cfee2e4d0ede to your computer and use it in GitHub Desktop.
Bash wrapper to run only one command in a time
#! /bin/bash
ENV_FILE=/etc/container_env
set -a
source "${ENV_FILE}"
set +a
function set_trap(){
local function_name="${1}"
local signal_name="${2}"
local current_trap
local current_code
[[ -z "${function_name}" || -z "${signal_name}" ]] && return 1
current_trap=$(trap -p "${signal_name}")
if [[ -z "${current_trap}" ]];then
eval "trap '${function_name}' ${signal_name}"
return 0
fi
current_code=$(echo "${current_trap}" \
|sed -E "s/trap -- (['\"]?)(.+)\1 ${signal_name}/\2/")
eval "trap -- '${function_name};${current_code}' ${signal_name}"
return 0
}
function file_lock(){
local file_path="${1}"
local lock_fd=200
[[ -f "${file_path}" ]] || touch "${file_path}"
eval "exec ${lock_fd}>${file_path}"
flock -n "${lock_fd}" || return 1
echo "${$}" > "${file_path}"
return 0
}
export -f file_lock
function file_unlock(){
local file_path="${1}"
local lock_fd=200
eval "exec ${lock_fd}>&-"
return 0
}
export -f file_unlock
if [[ "${#}" -lt 1 ]];then
echo "Usage: ${0} <command>"
exit 1
fi
command=${*}
command_hash=$(echo "${command}"|md5sum|awk '{print $1}')
command_file="/tmp/run_one-${command_hash}.lock"
if ! file_lock "${command_file}";then
echo "Command already running: ${command}"
exit 0
fi
set_trap "rm -f ${command_file}" EXIT
set_trap "file_unlock ${command_file}" EXIT
${command}
# vi:syntax=sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment