116038816SMartin Matuska# Copyright (c) 2010-2016, Aneurin Price <aneurin.price@gmail.com> 216038816SMartin Matuska 316038816SMartin Matuska# Permission is hereby granted, free of charge, to any person 416038816SMartin Matuska# obtaining a copy of this software and associated documentation 516038816SMartin Matuska# files (the "Software"), to deal in the Software without 616038816SMartin Matuska# restriction, including without limitation the rights to use, 716038816SMartin Matuska# copy, modify, merge, publish, distribute, sublicense, and/or sell 816038816SMartin Matuska# copies of the Software, and to permit persons to whom the 916038816SMartin Matuska# Software is furnished to do so, subject to the following 1016038816SMartin Matuska# conditions: 1116038816SMartin Matuska 1216038816SMartin Matuska# The above copyright notice and this permission notice shall be 1316038816SMartin Matuska# included in all copies or substantial portions of the Software. 1416038816SMartin Matuska 1516038816SMartin Matuska# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1616038816SMartin Matuska# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 1716038816SMartin Matuska# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1816038816SMartin Matuska# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 1916038816SMartin Matuska# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 2016038816SMartin Matuska# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2116038816SMartin Matuska# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2216038816SMartin Matuska# OTHER DEALINGS IN THE SOFTWARE. 2316038816SMartin Matuska 2416038816SMartin Matuska__ZFS_CMD="@sbindir@/zfs" 2516038816SMartin Matuska__ZPOOL_CMD="@sbindir@/zpool" 2616038816SMartin Matuska 2716038816SMartin Matuska# Disable bash's built-in hostname completion, as this makes it impossible to 2816038816SMartin Matuska# provide completions containing an @-sign, which is necessary for completing 2916038816SMartin Matuska# snapshot names. If bash_completion is in use, this will already be disabled 3016038816SMartin Matuska# and replaced with better completions anyway. 3116038816SMartin Matuskashopt -u hostcomplete 3216038816SMartin Matuska 3316038816SMartin Matuska__zfs_get_commands() 3416038816SMartin Matuska{ 3516038816SMartin Matuska $__ZFS_CMD 2>&1 | awk '/^\t[a-z]/ {print $1}' | cut -f1 -d '|' | uniq 3616038816SMartin Matuska} 3716038816SMartin Matuska 3816038816SMartin Matuska__zfs_get_properties() 3916038816SMartin Matuska{ 4016038816SMartin Matuska $__ZFS_CMD get 2>&1 | awk '$2 == "YES" || $2 == "NO" {print $1}'; echo all name space 4116038816SMartin Matuska} 4216038816SMartin Matuska 4316038816SMartin Matuska__zfs_get_editable_properties() 4416038816SMartin Matuska{ 4516038816SMartin Matuska $__ZFS_CMD get 2>&1 | awk '$2 == "YES" {print $1"="}' 4616038816SMartin Matuska} 4716038816SMartin Matuska 4816038816SMartin Matuska__zfs_get_inheritable_properties() 4916038816SMartin Matuska{ 5016038816SMartin Matuska $__ZFS_CMD get 2>&1 | awk '$3 == "YES" {print $1}' 5116038816SMartin Matuska} 5216038816SMartin Matuska 5316038816SMartin Matuska__zfs_list_datasets() 5416038816SMartin Matuska{ 5516038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$@" 5616038816SMartin Matuska} 5716038816SMartin Matuska 5816038816SMartin Matuska__zfs_list_filesystems() 5916038816SMartin Matuska{ 6016038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t filesystem 6116038816SMartin Matuska} 6216038816SMartin Matuska 6316038816SMartin Matuska__zfs_match_snapshot() 6416038816SMartin Matuska{ 6516038816SMartin Matuska local base_dataset="${cur%@*}" 66*bb2d13b6SMartin Matuska if [[ "$base_dataset" != "$cur" ]] 6716038816SMartin Matuska then 6816038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" 6916038816SMartin Matuska else 70*bb2d13b6SMartin Matuska if [[ "$cur" != "" ]] && __zfs_list_datasets "$cur" &> /dev/null 7116038816SMartin Matuska then 72681ce946SMartin Matuska $__ZFS_CMD list -H -o name -s name -t filesystem,volume -r "$cur" | tail -n +2 7316038816SMartin Matuska # We output the base dataset name even though we might be 7416038816SMartin Matuska # completing a command that can only take a snapshot, because it 7516038816SMartin Matuska # prevents bash from considering the completion finished when it 7616038816SMartin Matuska # ends in the bare @. 7716038816SMartin Matuska echo "$cur" 7816038816SMartin Matuska echo "$cur@" 7916038816SMartin Matuska else 8016038816SMartin Matuska local datasets 8116038816SMartin Matuska datasets="$(__zfs_list_datasets)" 8216038816SMartin Matuska # As above 8316038816SMartin Matuska echo "$datasets" 8416038816SMartin Matuska if [[ "$cur" == */ ]] 8516038816SMartin Matuska then 8616038816SMartin Matuska # If the current command ends with a slash, then the only way 8716038816SMartin Matuska # it can be completed with a single tab press (ie. in this pass) 8816038816SMartin Matuska # is if it has exactly one child, so that's the only time we 8916038816SMartin Matuska # need to offer a suggestion with an @ appended. 9016038816SMartin Matuska local num_children 9116038816SMartin Matuska # This is actually off by one as zfs list includes the named 9216038816SMartin Matuska # dataset in addition to its children 9316038816SMartin Matuska num_children=$(__zfs_list_datasets -d 1 "${cur%/}" 2> /dev/null | wc -l) 9416038816SMartin Matuska if [[ $num_children != 2 ]] 9516038816SMartin Matuska then 9616038816SMartin Matuska return 0 9716038816SMartin Matuska fi 9816038816SMartin Matuska fi 9916038816SMartin Matuska echo "$datasets" | awk '{print $1 "@"}' 10016038816SMartin Matuska fi 10116038816SMartin Matuska fi 10216038816SMartin Matuska} 10316038816SMartin Matuska 10416038816SMartin Matuska__zfs_match_snapshot_or_bookmark() 10516038816SMartin Matuska{ 10616038816SMartin Matuska local base_dataset="${cur%[#@]*}" 107*bb2d13b6SMartin Matuska if [[ "$base_dataset" != "$cur" ]] 10816038816SMartin Matuska then 10916038816SMartin Matuska if [[ $cur == *@* ]] 11016038816SMartin Matuska then 11116038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" 11216038816SMartin Matuska else 11316038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t bookmark -d 1 "$base_dataset" 11416038816SMartin Matuska fi 11516038816SMartin Matuska else 11616038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t filesystem,volume 117*bb2d13b6SMartin Matuska if [[ -e "$cur" ]] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$cur" &> /dev/null 11816038816SMartin Matuska then 11916038816SMartin Matuska echo "$cur@" 12016038816SMartin Matuska echo "$cur#" 12116038816SMartin Matuska fi 12216038816SMartin Matuska fi 12316038816SMartin Matuska} 12416038816SMartin Matuska 12516038816SMartin Matuska__zfs_match_multiple_snapshots() 12616038816SMartin Matuska{ 12716038816SMartin Matuska local existing_opts 12816038816SMartin Matuska existing_opts="$(expr "$cur" : '\(.*\)[%,]')" 129*bb2d13b6SMartin Matuska if [[ -e "$existing_opts" ]] 13016038816SMartin Matuska then 13116038816SMartin Matuska local base_dataset="${cur%@*}" 132*bb2d13b6SMartin Matuska if [[ "$base_dataset" != "$cur" ]] 13316038816SMartin Matuska then 13416038816SMartin Matuska local cur="${cur##*,}" 13516038816SMartin Matuska if [[ $cur =~ ^%|%.*% ]] 13616038816SMartin Matuska then 13716038816SMartin Matuska # correct range syntax is start%end 13816038816SMartin Matuska return 1 13916038816SMartin Matuska fi 14016038816SMartin Matuska local range_start 14116038816SMartin Matuska range_start="$(expr "$cur" : '\(.*%\)')" 14216038816SMartin Matuska # shellcheck disable=SC2016 14316038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" | sed 's$.*@$'"$range_start"'$g' 14416038816SMartin Matuska fi 14516038816SMartin Matuska else 14616038816SMartin Matuska __zfs_match_snapshot_or_bookmark 14716038816SMartin Matuska fi 14816038816SMartin Matuska} 14916038816SMartin Matuska 15016038816SMartin Matuska__zfs_list_volumes() 15116038816SMartin Matuska{ 15216038816SMartin Matuska $__ZFS_CMD list -H -o name -s name -t volume 15316038816SMartin Matuska} 15416038816SMartin Matuska 15516038816SMartin Matuska__zfs_argument_chosen() 15616038816SMartin Matuska{ 15716038816SMartin Matuska local word property 15816038816SMartin Matuska for word in $(seq $((COMP_CWORD-1)) -1 2) 15916038816SMartin Matuska do 16016038816SMartin Matuska local prev="${COMP_WORDS[$word]}" 16116038816SMartin Matuska if [[ ${COMP_WORDS[$word-1]} != -[tos] ]] 16216038816SMartin Matuska then 16316038816SMartin Matuska if [[ "$prev" == [^,]*,* ]] || [[ "$prev" == *[@:\#]* ]] 16416038816SMartin Matuska then 16516038816SMartin Matuska return 0 16616038816SMartin Matuska fi 16716038816SMartin Matuska for property in "$@" 16816038816SMartin Matuska do 16916038816SMartin Matuska if [[ $prev == "$property"* ]] 17016038816SMartin Matuska then 17116038816SMartin Matuska return 0 17216038816SMartin Matuska fi 17316038816SMartin Matuska done 17416038816SMartin Matuska fi 17516038816SMartin Matuska done 17616038816SMartin Matuska return 1 17716038816SMartin Matuska} 17816038816SMartin Matuska 17916038816SMartin Matuska__zfs_complete_ordered_arguments() 18016038816SMartin Matuska{ 18116038816SMartin Matuska local list1=$1 18216038816SMartin Matuska local list2=$2 18316038816SMartin Matuska local cur=$3 18416038816SMartin Matuska local extra=$4 18516038816SMartin Matuska # shellcheck disable=SC2086 18616038816SMartin Matuska if __zfs_argument_chosen $list1 18716038816SMartin Matuska then 188681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$list2 $extra" -- "$cur") 18916038816SMartin Matuska else 190681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$list1 $extra" -- "$cur") 19116038816SMartin Matuska fi 19216038816SMartin Matuska} 19316038816SMartin Matuska 19416038816SMartin Matuska__zfs_complete_multiple_options() 19516038816SMartin Matuska{ 19616038816SMartin Matuska local options=$1 19716038816SMartin Matuska local cur=$2 19816038816SMartin Matuska local existing_opts 19916038816SMartin Matuska 200681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$options" -- "${cur##*,}") 20116038816SMartin Matuska existing_opts=$(expr "$cur" : '\(.*,\)') 202*bb2d13b6SMartin Matuska if [[ -n "$existing_opts" ]] 20316038816SMartin Matuska then 20416038816SMartin Matuska COMPREPLY=( "${COMPREPLY[@]/#/${existing_opts}}" ) 20516038816SMartin Matuska fi 20616038816SMartin Matuska} 20716038816SMartin Matuska 20816038816SMartin Matuska__zfs_complete_switch() 20916038816SMartin Matuska{ 21016038816SMartin Matuska local options=$1 21116038816SMartin Matuska if [[ ${cur:0:1} == - ]] 21216038816SMartin Matuska then 213681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "-{$options}" -- "$cur") 21416038816SMartin Matuska return 0 21516038816SMartin Matuska else 21616038816SMartin Matuska return 1 21716038816SMartin Matuska fi 21816038816SMartin Matuska} 21916038816SMartin Matuska 22016038816SMartin Matuska__zfs_complete_nospace() 22116038816SMartin Matuska{ 22216038816SMartin Matuska # Google indicates that there may still be bash versions out there that 22316038816SMartin Matuska # don't have compopt. 22416038816SMartin Matuska if type compopt &> /dev/null 22516038816SMartin Matuska then 22616038816SMartin Matuska compopt -o nospace 22716038816SMartin Matuska fi 22816038816SMartin Matuska} 22916038816SMartin Matuska 23016038816SMartin Matuska__zfs_complete() 23116038816SMartin Matuska{ 23216038816SMartin Matuska local cur prev cmd cmds 23316038816SMartin Matuska COMPREPLY=() 23416038816SMartin Matuska if type _get_comp_words_by_ref &> /dev/null 23516038816SMartin Matuska then 23616038816SMartin Matuska # Don't split on colon 23716038816SMartin Matuska _get_comp_words_by_ref -n : -c cur -p prev -w COMP_WORDS -i COMP_CWORD 23816038816SMartin Matuska else 23916038816SMartin Matuska cur="${COMP_WORDS[COMP_CWORD]}" 24016038816SMartin Matuska prev="${COMP_WORDS[COMP_CWORD-1]}" 24116038816SMartin Matuska fi 24216038816SMartin Matuska cmd="${COMP_WORDS[1]}" 24316038816SMartin Matuska 24416038816SMartin Matuska if [[ ${prev##*/} == zfs ]] 24516038816SMartin Matuska then 24616038816SMartin Matuska cmds=$(__zfs_get_commands) 247681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$cmds -?" -- "$cur") 24816038816SMartin Matuska return 0 24916038816SMartin Matuska fi 25016038816SMartin Matuska 25116038816SMartin Matuska case "${cmd}" in 25216038816SMartin Matuska bookmark) 25316038816SMartin Matuska if __zfs_argument_chosen 25416038816SMartin Matuska then 255681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "${prev%@*}# ${prev/@/#}" -- "$cur") 25616038816SMartin Matuska else 257681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 25816038816SMartin Matuska fi 25916038816SMartin Matuska ;; 26016038816SMartin Matuska clone) 26116038816SMartin Matuska case "${prev}" in 26216038816SMartin Matuska -o) 263681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_get_editable_properties)" -- "$cur") 26416038816SMartin Matuska __zfs_complete_nospace 26516038816SMartin Matuska ;; 26616038816SMartin Matuska *) 26716038816SMartin Matuska if ! __zfs_complete_switch "o,p" 26816038816SMartin Matuska then 26916038816SMartin Matuska if __zfs_argument_chosen 27016038816SMartin Matuska then 271681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_list_datasets)" -- "$cur") 27216038816SMartin Matuska else 273681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 27416038816SMartin Matuska fi 27516038816SMartin Matuska fi 27616038816SMartin Matuska ;; 27716038816SMartin Matuska esac 27816038816SMartin Matuska ;; 27916038816SMartin Matuska get) 28016038816SMartin Matuska case "${prev}" in 28116038816SMartin Matuska -d) 282681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "" -- "$cur") 28316038816SMartin Matuska ;; 28416038816SMartin Matuska -t) 28516038816SMartin Matuska __zfs_complete_multiple_options "filesystem volume snapshot bookmark all" "$cur" 28616038816SMartin Matuska ;; 28716038816SMartin Matuska -s) 28816038816SMartin Matuska __zfs_complete_multiple_options "local default inherited temporary received none" "$cur" 28916038816SMartin Matuska ;; 29016038816SMartin Matuska -o) 29116038816SMartin Matuska __zfs_complete_multiple_options "name property value source received all" "$cur" 29216038816SMartin Matuska ;; 29316038816SMartin Matuska *) 29416038816SMartin Matuska if ! __zfs_complete_switch "H,r,p,d,o,t,s" 29516038816SMartin Matuska then 29616038816SMartin Matuska # shellcheck disable=SC2046 29716038816SMartin Matuska if __zfs_argument_chosen $(__zfs_get_properties) 29816038816SMartin Matuska then 299681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 30016038816SMartin Matuska else 30116038816SMartin Matuska __zfs_complete_multiple_options "$(__zfs_get_properties)" "$cur" 30216038816SMartin Matuska fi 30316038816SMartin Matuska fi 30416038816SMartin Matuska ;; 30516038816SMartin Matuska esac 30616038816SMartin Matuska ;; 30716038816SMartin Matuska inherit) 30816038816SMartin Matuska if ! __zfs_complete_switch "r" 30916038816SMartin Matuska then 31016038816SMartin Matuska __zfs_complete_ordered_arguments "$(__zfs_get_inheritable_properties)" "$(__zfs_match_snapshot)" "$cur" 31116038816SMartin Matuska fi 31216038816SMartin Matuska ;; 31316038816SMartin Matuska list) 31416038816SMartin Matuska case "${prev}" in 31516038816SMartin Matuska -d) 316681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "" -- "$cur") 31716038816SMartin Matuska ;; 31816038816SMartin Matuska -t) 31916038816SMartin Matuska __zfs_complete_multiple_options "filesystem volume snapshot bookmark all" "$cur" 32016038816SMartin Matuska ;; 32116038816SMartin Matuska -o) 32216038816SMartin Matuska __zfs_complete_multiple_options "$(__zfs_get_properties)" "$cur" 32316038816SMartin Matuska ;; 32416038816SMartin Matuska -s|-S) 325681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_get_properties)" -- "$cur") 32616038816SMartin Matuska ;; 32716038816SMartin Matuska *) 32816038816SMartin Matuska if ! __zfs_complete_switch "H,r,d,o,t,s,S" 32916038816SMartin Matuska then 330681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 33116038816SMartin Matuska fi 33216038816SMartin Matuska ;; 33316038816SMartin Matuska esac 33416038816SMartin Matuska ;; 33516038816SMartin Matuska promote) 336681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_list_filesystems)" -- "$cur") 33716038816SMartin Matuska ;; 33816038816SMartin Matuska rollback) 33916038816SMartin Matuska if ! __zfs_complete_switch "r,R,f" 34016038816SMartin Matuska then 341681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 34216038816SMartin Matuska fi 34316038816SMartin Matuska ;; 34416038816SMartin Matuska send) 34516038816SMartin Matuska if ! __zfs_complete_switch "D,n,P,p,R,v,e,L,i,I" 34616038816SMartin Matuska then 34716038816SMartin Matuska if __zfs_argument_chosen 34816038816SMartin Matuska then 349681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 35016038816SMartin Matuska else 35116038816SMartin Matuska if [[ $prev == -*i* ]] 35216038816SMartin Matuska then 353681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot_or_bookmark)" -- "$cur") 35416038816SMartin Matuska else 355681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 35616038816SMartin Matuska fi 35716038816SMartin Matuska fi 35816038816SMartin Matuska fi 35916038816SMartin Matuska ;; 36016038816SMartin Matuska snapshot) 36116038816SMartin Matuska case "${prev}" in 36216038816SMartin Matuska -o) 363681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_get_editable_properties)" -- "$cur") 36416038816SMartin Matuska __zfs_complete_nospace 36516038816SMartin Matuska ;; 36616038816SMartin Matuska *) 36716038816SMartin Matuska if ! __zfs_complete_switch "o,r" 36816038816SMartin Matuska then 369681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 37016038816SMartin Matuska __zfs_complete_nospace 37116038816SMartin Matuska fi 37216038816SMartin Matuska ;; 37316038816SMartin Matuska esac 37416038816SMartin Matuska ;; 37516038816SMartin Matuska set) 37616038816SMartin Matuska __zfs_complete_ordered_arguments "$(__zfs_get_editable_properties)" "$(__zfs_match_snapshot)" "$cur" 37716038816SMartin Matuska __zfs_complete_nospace 37816038816SMartin Matuska ;; 37916038816SMartin Matuska upgrade) 38016038816SMartin Matuska case "${prev}" in 38116038816SMartin Matuska -a|-V|-v) 382681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "" -- "$cur") 38316038816SMartin Matuska ;; 38416038816SMartin Matuska *) 38516038816SMartin Matuska if ! __zfs_complete_switch "a,V,v,r" 38616038816SMartin Matuska then 387681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_list_filesystems)" -- "$cur") 38816038816SMartin Matuska fi 38916038816SMartin Matuska ;; 39016038816SMartin Matuska esac 39116038816SMartin Matuska ;; 39216038816SMartin Matuska destroy) 39316038816SMartin Matuska if ! __zfs_complete_switch "d,f,n,p,R,r,v" 39416038816SMartin Matuska then 39516038816SMartin Matuska __zfs_complete_multiple_options "$(__zfs_match_multiple_snapshots)" "$cur" 39616038816SMartin Matuska __zfs_complete_nospace 39716038816SMartin Matuska fi 39816038816SMartin Matuska ;; 39916038816SMartin Matuska *) 400681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur") 40116038816SMartin Matuska ;; 40216038816SMartin Matuska esac 40316038816SMartin Matuska if type __ltrim_colon_completions &> /dev/null 40416038816SMartin Matuska then 40516038816SMartin Matuska __ltrim_colon_completions "$cur" 40616038816SMartin Matuska fi 40716038816SMartin Matuska return 0 40816038816SMartin Matuska} 40916038816SMartin Matuska 41016038816SMartin Matuska__zpool_get_commands() 41116038816SMartin Matuska{ 41216038816SMartin Matuska $__ZPOOL_CMD 2>&1 | awk '/^\t[a-z]/ {print $1}' | uniq 41316038816SMartin Matuska} 41416038816SMartin Matuska 41516038816SMartin Matuska__zpool_get_properties() 41616038816SMartin Matuska{ 41716038816SMartin Matuska $__ZPOOL_CMD get 2>&1 | awk '$2 == "YES" || $2 == "NO" {print $1}'; echo all 41816038816SMartin Matuska} 41916038816SMartin Matuska 42016038816SMartin Matuska__zpool_get_editable_properties() 42116038816SMartin Matuska{ 42216038816SMartin Matuska $__ZPOOL_CMD get 2>&1 | awk '$2 == "YES" {print $1"="}' 42316038816SMartin Matuska} 42416038816SMartin Matuska 42516038816SMartin Matuska__zpool_list_pools() 42616038816SMartin Matuska{ 42716038816SMartin Matuska $__ZPOOL_CMD list -H -o name 42816038816SMartin Matuska} 42916038816SMartin Matuska 43016038816SMartin Matuska__zpool_complete() 43116038816SMartin Matuska{ 43216038816SMartin Matuska local cur prev cmd cmds pools 43316038816SMartin Matuska COMPREPLY=() 43416038816SMartin Matuska cur="${COMP_WORDS[COMP_CWORD]}" 43516038816SMartin Matuska prev="${COMP_WORDS[COMP_CWORD-1]}" 43616038816SMartin Matuska cmd="${COMP_WORDS[1]}" 43716038816SMartin Matuska 43816038816SMartin Matuska if [[ ${prev##*/} == zpool ]] 43916038816SMartin Matuska then 44016038816SMartin Matuska cmds=$(__zpool_get_commands) 441681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$cmds" -- "$cur") 44216038816SMartin Matuska return 0 44316038816SMartin Matuska fi 44416038816SMartin Matuska 44516038816SMartin Matuska case "${cmd}" in 44616038816SMartin Matuska get) 44716038816SMartin Matuska __zfs_complete_ordered_arguments "$(__zpool_get_properties)" "$(__zpool_list_pools)" "$cur" 44816038816SMartin Matuska return 0 44916038816SMartin Matuska ;; 45016038816SMartin Matuska import) 45116038816SMartin Matuska if [[ $prev == -d ]] 45216038816SMartin Matuska then 45316038816SMartin Matuska _filedir -d 45416038816SMartin Matuska else 455681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zpool_list_pools) -d" -- "$cur") 45616038816SMartin Matuska fi 45716038816SMartin Matuska return 0 45816038816SMartin Matuska ;; 45916038816SMartin Matuska set) 46016038816SMartin Matuska __zfs_complete_ordered_arguments "$(__zpool_get_editable_properties)" "$(__zpool_list_pools)" "$cur" 46116038816SMartin Matuska __zfs_complete_nospace 46216038816SMartin Matuska return 0 46316038816SMartin Matuska ;; 46416038816SMartin Matuska add|attach|clear|create|detach|offline|online|remove|replace) 46516038816SMartin Matuska pools="$(__zpool_list_pools)" 46616038816SMartin Matuska # shellcheck disable=SC2086 46716038816SMartin Matuska if __zfs_argument_chosen $pools 46816038816SMartin Matuska then 46916038816SMartin Matuska _filedir 47016038816SMartin Matuska else 471681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$pools" -- "$cur") 47216038816SMartin Matuska fi 47316038816SMartin Matuska return 0 47416038816SMartin Matuska ;; 47516038816SMartin Matuska *) 476681ce946SMartin Matuska mapfile -t COMPREPLY < <(compgen -W "$(__zpool_list_pools)" -- "$cur") 47716038816SMartin Matuska return 0 47816038816SMartin Matuska ;; 47916038816SMartin Matuska esac 48016038816SMartin Matuska 48116038816SMartin Matuska} 48216038816SMartin Matuska 48316038816SMartin Matuskacomplete -F __zfs_complete zfs 48416038816SMartin Matuskacomplete -F __zpool_complete zpool 485