こんなスクリプトをつくって(とりあえず名前はexecsとした)
#!/bin/sh PROG="$0" MODE="EXEC" MARK="%%" BACKGOUND=NO while [ $# -gt 0 ]; do case "$1" in -n) MODE=DRYRUN ;; -m) shift MARK="$1" ;; -b) MODE=BACKGROUND ;; -*) echo "$PROG: invalid argument: $1" exit 1 ;; *) break ;; esac shift done if [ $# -eq 0 ]; then echo "$PROG: no command specified." exit 1 fi TEMPLATE="$*" while read ARG; do CMD=$(echo "$TEMPLATE" | sed "s|$MARK|$ARG|g") case $MODE in DRYRUN) echo "$CMD" ;; EXEC) echo "+ $CMD" $CMD ;; BACKGROUND) echo "+ $CMD &" $CMD & ;; *) echo "$PROG: INTERNAL ERROR" exit 1 ;; esac done case $MODE in BACKGROUND) wait ;; esac exit 0こんなふうにするとよい。
zfs list -t snapshot -r -H -o name tank/foo/bar | \ execs -b zfs destroy %%複数を同時実行した方が(たぶんuberblockの書き込み回数が減るから?)かなり速くなるので execs -bオプションは必須。ちなみにzfs destroyは1引数しか取れないので、xargsをつかうときには以下のように-n1オプションを付ける必要がある。
zfs list ... | xargs -n1 zfs destroyzfs listとexecsのあいだにgrepでフィルタすることもできる。たとえばスナップショット名が "dailyなんとか" のものだけを消したい場合には
zfs list -t snapshot -r -H -o name tank | \ grep "@daily" | execs -b zfs destroy %%tank/fooの下は消したいけどtank/foo/barは残したいなら
zfs list -t snapshot -r -H -o name tank/foo | \ grep -v ^tank/foo/bar | execs -b zfs destroy %%ちなみに、tank/foo直下のスナップショットだけリストするには
zfs list -t snapshot -r -d 1 tank/foo