# mount(8) completion. This will pull a list of possible mounts out of # /etc/{,v}fstab, unless the word being completed contains a ':', which # would indicate the specification of an NFS server. In that case, we # query the server for a list of all available exports and complete on # that instead. # have mount && { # Just like COMPREPLY=(`compgen -W "${COMPREPLY[*]}" -- "$cur"`), only better! # # This will correctly escape special characters in COMPREPLY. _reply_compgen_array() { # Create the argument for compgen -W by escaping twice. # # One round of escape is because we want to reply with escaped arguments. A # second round is required because compgen -W will helpfully expand it's # argument. local i wlist for i in ${!COMPREPLY[*]}; do local q=$(quote "$(printf %q "${COMPREPLY[$i]}")") wlist+=$q$'\n' done # We also have to add another round of escaping to $cur. local ecur="$cur" ecur="${ecur//\\/\\\\}" ecur="${ecur//\'/\'}" # Actually generate completions. local oldifs=$IFS IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)' IFS=$oldifs } # Unescape strings in the linux fstab(5) format (with octal escapes). __linux_fstab_unescape() { eval $1="'${!1//\'/\047}'" eval $1="'${!1/%\\/\\\\}'" eval "$1=$'${!1}'" } # Complete linux fstab entries. # # Reads a file from stdin in the linux fstab(5) format; as used by /etc/fstab # and /proc/mounts. _linux_fstab() { COMPREPLY=() # Read and unescape values into COMPREPLY local fs_spec fs_file fs_other local oldifs="$IFS" while read -r fs_spec fs_file fs_other; do if [[ $fs_spec = [#]* ]]; then continue; fi if [[ $1 == -L ]]; then local fs_label=${fs_spec/#LABEL=} if [[ $fs_label != "$fs_spec" ]]; then __linux_fstab_unescape fs_label IFS=$'\0' COMPREPLY+=("$fs_label") IFS=$oldifs fi else __linux_fstab_unescape fs_spec __linux_fstab_unescape fs_file IFS=$'\0' [[ $fs_spec = */* ]] && COMPREPLY+=("$fs_spec") [[ $fs_file = */* ]] && COMPREPLY+=("$fs_file") IFS=$oldifs fi done _reply_compgen_array } _mount() { local cur sm host prev COMPREPLY=() _get_comp_words_by_ref -n : cur prev case $prev in -t|--types) _fstypes return 0 ;; esac [[ "$cur" == \\ ]] && cur="/" if [[ "$cur" == *:* ]]; then for sm in "$(type -P showmount)" {,/usr}/{,s}bin/showmount; do [ -x "$sm" ] || continue COMPREPLY=( $( compgen -W "$( "$sm" -e ${cur%%:*} | \ awk 'NR>1 {print $1}' )" -- "${cur#*:}" ) ) return 0 done fi if [[ "$cur" == //* ]]; then host=${cur#//} host=${host%%/*} if [ -n "$host" ]; then COMPREPLY=( $( compgen -P "//$host" -W \ "$( smbclient -d 0 -NL $host 2>/dev/null | sed -ne '/^['"$'\t '"']*Sharename/,/^$/p' | sed -ne '3,$s|^[^A-Za-z]*\([^'"$'\t '"']*\).*$|/\1|p' )" \ -- "${cur#//$host}" ) ) fi elif [ -r /etc/vfstab ]; then # Solaris COMPREPLY=( $( compgen -W "$( awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' /etc/vfstab )" -- "$cur" ) ) elif [ ! -e /etc/fstab ]; then # probably Cygwin COMPREPLY=( $( compgen -W "$( mount | awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' )" -- "$cur" ) ) else # probably Linux if [ "$prev" = -L ]; then _linux_fstab -L < /etc/fstab elif [ "$prev" = -U ]; then COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*UUID=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) ) else _linux_fstab < /etc/fstab fi fi return 0 } && complete -F _mount -o default -o dirnames mount # umount(8) completion. This relies on the mount point being the third # space-delimited field in the output of mount(8) # have umount && _umount() { local cur _get_comp_words_by_ref cur COMPREPLY=() if [[ $(uname -s) = Linux && -r /proc/mounts ]]; then # Linux /proc/mounts is properly quoted. This is important when # unmounting usb devices with pretty names. _linux_fstab < /proc/mounts else local IFS=$'\n' COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- "$cur" ) ) fi return 0 } && complete -F _umount -o dirnames umount } # Local variables: # mode: shell-script # sh-basic-offset: 4 # sh-indent-comment: t # indent-tabs-mode: nil # End: # ex: ts=4 sw=4 et filetype=sh