diff sbin/fzfs @ 529:703e9f357339

fzfs umount: umounting now also works for datasets and/or mountpoints that have spaces in their values. For this to work textproc/jq must be installed as /usr/local/bin/jq. "mount -p" is requested as JSON (via libxo) processed accordingly. This is because normally "mount -p" has a TAB as field separator -- with the exception of fields becoming to large; the a SPACE is used... "fzfs mount" works already in this cases.
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 04 Sep 2024 20:52:57 +0200
parents 93b98803219b
children 07071afd9ae5
line wrap: on
line diff
--- a/sbin/fzfs	Wed Sep 04 18:48:10 2024 +0200
+++ b/sbin/fzfs	Wed Sep 04 20:52:57 2024 +0200
@@ -302,24 +302,37 @@
     OPTIND=1
 
     _dsname="${1-}"
-    [ -z "${_dsname}" ] && { echo "ERROR: no dataset given" 1>&2; return 2; }
+    [ -z "${_dsname}" ] && { err "no dataset given"; return 2; }
 
     # Just determine whether the given dataset name exists
-    _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}")" || { echo "ERROR: dataset not found" 1>&2; return 1; }
+    _rootds_mountpoint="$(zfs list -H -o mountpoint -t filesystem "${_dsname}" 1>/dev/null 2>/dev/null)" || { err "dataset not found"; return 1; }
 
-    /sbin/mount -t zfs -p \
-    | LC_ALL=C GREP_OPTIONS="" /usr/bin/egrep "^${_dsname}(/|\s)" \
-    | /usr/bin/sort -n -r \
-    | {
-        while IFS=' '$'\t' read -r _name _mp _rest ; do
+    if [ -x "${JQ}" ]; then
+        /sbin/mount -t zfs -p --libxo=json,no-locale \
+        | LC_ALL=C "${JQ}" -r $'.mount.fstab.[] | [.device, .mntpoint, .fstype, .opts, .dump, .pass] | @tsv ' \
+        | LC_ALL=C /usr/bin/awk -F $'\\t+' -v OFS=$'\t' -v ds1="${_dsname}" -v ds2="${_dsname}/" $'{ if (($1 == ds1) || (index($1, ds2) == 1)) { print $1, $2; } }' \
+        | LC_ALL=C /usr/bin/sort -t $'\t' -k 1 -r \
+        | while IFS=$'\t' read -r _name _mp ; do
             if checkyes _opt_dry_run ; then
                 echo "Would umount ${_name} from ${_mp}"
             else
                 echo "Umounting ${_name} on ${_mp}"
                 /sbin/umount "${_mp}" || return 1
             fi
-        done
-    }
+          done
+    else
+        /sbin/mount -t zfs -p \
+        | LC_ALL=C GREP_OPTIONS="" /usr/bin/egrep "^${_dsname}(/|\s)" \
+        | LC_ALL=C /usr/bin/sort -n -r \
+        | while IFS=' '$'\t' read -r _name _mp _rest ; do
+            if checkyes _opt_dry_run ; then
+                echo "Would umount ${_name} from ${_mp}"
+            else
+                echo "Umounting ${_name} on ${_mp}"
+                /sbin/umount "${_mp}" || return 1
+            fi
+          done
+    fi
     return 0
 }