Package: pmount
Version: 0.9.23-3+b2
Severity: normal
Tags: patch
File: /etc/bash_completion.d/pmount
When I used tab-completion on a pmount command, it would hang
indefinitely. The problem was here:
/--------
| grep $mdir /proc/mounts
\--------
Because $mdir isn't set in _pmount(), grep sees only one argument
"/proc/mounts", which it interprets as the search regexp, and so it
waits for input on stdin.
A simple fix would be to copy the initialisation of $mdir from
_pumount(), but I got carried away: I was frustrated by being unable to
complete using the links in /dev/disk/by-*/.
So I include a pair of completions, to go into the more modern location
of /usr/share/bash-completion/completions:
_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
_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
I think these are a better match for what pmount and pumount accept as
arguments. I've tested them with a variety of removable media (with
various partition layouts and some with multiple LUNs) and have been
using this frequently over the past year or so without problems.
I requested a code review, but received no answers,
at https://codereview.stackexchange.com/q/191141
The version I'm using does depend on awk - if that's a problem, I've
included a sed version (commented out) that does the same thing, but
less clearly IMO.
-- System Information:
Debian Release: buster/sid
APT prefers testing
APT policy: (900, 'testing'), (900, 'stable'), (400, 'unstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386, armel
Kernel: Linux 4.17.0-1-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8),
LANGUAGE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
Versions of packages pmount depends on:
ii libblkid1 2.32.1-0.1
ii libc6 2.27-5
pmount recommends no packages.
Versions of packages pmount suggests:
pn cryptsetup <none>