Функции автодополнение Bash для pmount и pumount


Я нашел проблему с Debian Баш-завершение pmount и pumountи предназначен для добавления патч на баг-репорт - но я увлекся, и в итоге полностью переписать завершения функции.

Оригинал был в /etc/bash_completion.d/pmountно современный подход-иметь два файла в /usr/share/bash-completion/completions/ чтобы поддержать спрос-загрузка завершения функции. Мы предполагаем, что _init_completion является частью этого механизма, чтобы инициализировать переменные оболочки cur и prev С большей пользой, чем обычно $2 и $3 (например, пропуск перенаправление слова).

Я пошел в некоторые длины, чтобы найти фактическое доступных кодировок и файловая система типы, которые могут быть использованы, но волосатую код в поиске доступных имен для устройств (я хотел бы быть в состоянии использовать символические ссылки /dev/disk/by-label/ для обеспечения я использую устройстве/разделе я ожидал, например).


/usr/share/bash-completion/completions/pmount

_pmount() {
    # shellcheck disable=SC2034
    local cur prev words cword
    _init_completion || return

   case "$prev" in
       -@(t|-type))
      COMPREPLY=($(grep "^[[:space:]]$cur" /proc/filesystems) $(find "/lib/modules/$(uname -r)/kernel/fs" -name "*.ko" -print0 | xargs -r -0 /sbin/modinfo | sed -ne 's/^alias: *fs-//p' | grep "^$cur"))
      return 0
      ;;

      -@(c|-charset))
      local encodings=(/sys/module/nls_* $(find "/lib/modules/$(uname -r)/kernel/fs/nls" -name '*.ko' -print0 | xargs -r -0 /sbin/modinfo | sed -ne 's/^\(name\|alias\): *//p'))
      COMPREPLY=($(compgen -W "${encodings[*]##*nls_}" -- "$cur"))
      return 0
      ;;
      -@(u|d|f|-umask|-dmask|-fmask))
      case "$cur" in
          '') COMPREPLY=( {0..7} ) ;;
          [0-7]|[0-7][0-7]) COMPREPLY=( $cur{0..7} ) ;;
          [0-7][0-7][0-7]) COMPREPLY=( $cur ) ;;
          *) return 1 ;;
      esac
      return 0
      ;;

      -@(p|-passphrase))
      _filedir
      return 0
      ;;

   esac

   if [[ "$cur" == -* ]]; then
        # transform "--help" output into completion list
       COMPREPLY=($(compgen -W "$(pmount --help | sed -e '/^..-/!d' -e 's/:.*//' -e 's/<[^>]*>//g' -e 'y/,/ /')" -- "$cur"))
   else
       local i allowed removable devices search
       local IFS=$'\n'
       allowed=($(grep -v '^[[:space:]]*#' /etc/pmount.allow))
       removable=($(for i in /sys/block/*
                    do
                        grep -Fxq 1 "$i/removable" || continue
                        # Replace with its partitions, if it has any - N.B. final /. is crucial, as
                        # subsystem entries are symlinks!
                        find "$i"/*/subsystem/. -maxdepth 0 -samefile "$i"/subsystem/. -print0 \
                            | awk -F/ -v RS='\0' -v i="${i##*/}" '{print"/dev/"$(NF-2)} END{if(!NR)print"/dev/"i}'
                        # # alternative non-awk version:
                        # j=$(find "$i"/*/subsystem/. -maxdepth 0 -samefile "$i"/subsystem/. -exec dirname '{}' \;)
                        # sed -e 's,.*/,/dev/,' <<<"${j:-$i}"
                    done))
       # Select only actual block devices that aren't already mounted
       # N.B. expansion of $allowed is unquoted, as wildcards are permitted
       devices=($(for i in ${allowed[*]} "${removable[@]}"; do test -b "$i" && echo "$i"; done | grep -vxF "$(cut -d' ' /proc/mounts -f1)"))
       test "${#devices[@]}" -gt 0 || return 0
       for i in "${devices[@]}"
       do search+=(-o -samefile "$i")
       done
       # alternative names - symlinks in /dev/disk/*/
       devices+=($(find -L /dev/disk -false "${search[@]}"))
       # all found names for mountable block devices, with and without initial /dev/
       COMPREPLY=($(compgen -W "$(printf '%q\n' "${devices[@]}" "${devices[@]#/dev/}")" -- "$cur"))
   fi
} &&
complete -F _pmount pmount

/usr/share/bash-completion/completions/pumount

_pumount() {
    # shellcheck disable=SC2034
    local cur prev words cword
    _init_completion || return

    if [[ "$cur" == -* ]]; then
        # transform "--help" output into completion list
       COMPREPLY=($(compgen -W "$(pumount --help | sed -e '/^..-/!d' -e 's/:.*//' -e 's/<[^>]*>//g' -e 'y/,/ /')" -- "$cur"))
   else
       local i mdir devices mounts search symlinks
       mdir=$(readlink -f /media)
       # shellcheck disable=SC2013
       for i in $(cut -d' ' -f1,2 /proc/mounts | grep -F " $mdir/")
       do
           # expand backslash escapes
           i=$(printf '%b' "$i")
           if test -b "$i"
           then
               search+=(-o -samefile "$i")
               devices+=("$i" "${i#/dev/}")
           elif test -d "$i"
           then
               mounts+=("$i" "${i#$mdir/}")
           fi
       done

       # alternative names - symlinks in /dev/disk/*/ and device or mountpoint basenames
       local IFS=$'\n'
       symlinks=($(find -L /dev/disk -false "${search[@]}"))
       COMPREPLY=($(compgen -W "$(printf '%q\n' "${mounts[@]}" "${devices[@]}" "${symlinks[@]}" "${symlinks[@]#/dev/}")" -- "$cur"))
   fi
} &&
complete -F _pumount pumount

Некоторые конкретные вопросы:

  • Я должен быть проверка, что такие команды, как modinfo на самом деле существует? Какие команды не нуждаются в проверке? (Я считаю, что grep и cut в "основных" пакетах, так что можно предположить, но я меньше уверен readlink, например).
  • Это гарантирует, что /media это единственное место, чтобы найти точки монтирования?
  • Я могу сделать эти длинные обернуть линии красиво без вреда для ясности?

Очевидно, что любые другие замечания или улучшения приглашаются тоже!



135
5
задан 3 апреля 2018 в 08:04 Источник Поделиться
Комментарии