こんなスクリプトをつくって(とりあえず名前は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














