aboutsummaryrefslogtreecommitdiff
path: root/bin/chc.sh
blob: ee030f5fe5c4b7b3212f8c1d20ccb0c2133610f3 (plain) (blame)
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
# Cache the output of a command and emit it straight from the cache if not
# expired on each run
self=chc

# Check arguments for sanity
if [ "$#" -lt 3 ] ; then
    printf >&2 '%s: Need a cache path, a duration, and a command\n' "$self"
    exit 2
fi

# First argument is the cache path, second is the duration in seconds
cac=$1 dur=$2
shift 2

# Get the current timestamp with uts(1df)
uts=$(uts) || exit

# Function checks cache exists, is readable, and not expired
fresh() {
    [ -f "$cac" ] || return
    [ -r "$cac" ] || return
    exp=$(sed 1q -- "$cac") || return
    [ "$((exp > uts))" -eq 1 ]
}

# Write runs the command and writes it to the cache
write() {
    exp=$((uts + dur))
    printf '%u\n' "$exp"
    "$@"
}

# If the cache isn't fresh, try to write a new one, or bail out
fresh "$cac" || write "$@" > "$cac" || exit

# Emit the content (exclude the first line, which is the timestamp)
sed 1d -- "$cac"