aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Linskey2025-08-13 16:15:04 -0400
committerBenjamin Linskey2025-08-13 16:24:08 -0400
commitb2db2aecc85ee8d5dd08dc4363c30566daa8f252 (patch)
treedb2bc613657a8632a6d7ed1be6bc1d65ecfbf2f1
parentf5f2300f42b29a35573be54afd55de0710699616 (diff)
downloadzfs-snapshots-b2db2aecc85ee8d5dd08dc4363c30566daa8f252.tar.gz

Fix -p -r behavior

Using the prune command with the recursive flag resulted in the script only pruning snapshots of the specified filesystem, ignoring their children.

-rwxr-xr-xsnapshots.sh51
1 files changed, 29 insertions, 22 deletions
diff --git a/snapshots.sh b/snapshots.sh
index e85262c..1e39183 100755
--- a/snapshots.sh
+++ b/snapshots.sh
@@ -52,10 +52,6 @@
set -e
-usage() {
- printf "usage: %s [-cplrnvh] [-t tag] [-k num] [dataset ...]\n" "$0"
-}
-
tag=
keep=
recursive=
@@ -65,6 +61,28 @@ create=
prune=
list=
+usage() {
+ printf "usage: %s [-cplrnvh] [-t tag] [-k num] [dataset ...]\n" "$0"
+}
+
+# Selectively destroys old snapshots for the filesystem specified by $1.
+# Behavior is controlled by the global variables $tag, $keep, $dry_run, and
+# $verbose.
+prune() {
+ snapshots=$(zfs list -t snapshot -o name -S name -H "$1")
+ to_delete=$(printf "%s\n" "$snapshots" | grep "@${tag}-" | tail -n +"$((keep + 1))")
+ for s in $to_delete; do
+ cmd="zfs destroy $s"
+ if [ -n "$dry_run" ] || [ -n "$verbose" ]; then
+ printf "%s\n" "$cmd"
+ fi
+
+ if [ -z "$dry_run" ]; then
+ $cmd
+ fi
+ done
+}
+
while getopts t:k:cplrknvh name; do
case $name in
t) tag="$OPTARG";;
@@ -119,12 +137,6 @@ if [ -n "$recursive" ]; then
fi
readonly create_cmd
-destroy_cmd='zfs destroy'
-if [ -n "$recursive" ]; then
- destroy_cmd="$destroy_cmd -R"
-fi
-readonly destroy_cmd
-
# Create snapshots.
if [ -n "$create" ]; then
for dataset in "$@"; do
@@ -146,18 +158,13 @@ fi
# Prune snapshots.
if [ -n "$prune" ]; then
for dataset in "$@"; do
- snapshots=$(zfs list -t snapshot -o name -S name -H "$dataset")
- to_delete=$(printf "%s\n" "$snapshots" | grep "@${tag}-" | tail -n +"$((keep + 1))")
- for s in $to_delete; do
- cmd="$destroy_cmd $s"
- if [ -n "$dry_run" ] || [ -n "$verbose" ]; then
- printf "%s\n" "$cmd"
- fi
-
- if [ -z "$dry_run" ]; then
- $cmd
- fi
- done
+ if [ -n "$recursive" ]; then
+ for filesystem in $(zfs list -t filesystem -o name -H -r "$dataset"); do
+ prune "$filesystem"
+ done
+ else
+ prune "$dataset"
+ fi
done
fi