pmount hangs on autocompletion

Posted on śro 09 maja 2018 in misc

Problem

Bash autocompletion is very good thing if works. If doesn't, becames pain in the ass. Like in Debian's pmount - when you type '/dev/sdc' hit tab and wait forever.

Problem is described in many places (eg here and here), so why shouldn't I describe it once more?

Reason

Script is in /etc/bash_completion.d/pmount. How to trace what exactly is doing there? Like that:

maho@dlaptop:~$ set -x

maho@dlaptop:~$ pmount /dev/<HIT TAB>+ local cur prev options devices fslist
+ options=' -r --read-only -w --read-write -s --sync -A --noatime -e --exec \
   -t filesystem --type filesystem -c charset --charset charset -u umask \
   --umask umask --dmask dmask --fmask fmask -p file --passphrase file \
   -h --help -d --debug -V --version'
+ fslist=' ascii cp1250 cp1251 cp1255 cp437 cp737 cp775 cp850 cp852 cp855 cp857 cp860 cp861 cp862 cp863 cp864 cp865 cp866 cp869 cp874 cp932 cp936 cp949 cp950 euc-jp iso8859-1 iso8859-13 iso8859-14 iso8859-15 iso8859-2 iso8859-3 iso8859-4 iso8859-5 iso8859-6 iso8859-7 iso8859-9 koi8-r koi8-ru koi8-u utf8'
+ COMPREPLY=()
+ cur=/dev/
+ prev=pmount
+ case "$prev" in
+ [[ /dev/ == -* ]]
+++ grep -v '^[[:space:]]*#' /etc/pmount.allow
++ sed -e 's,\(^/dev/\)\(.*\),\1\2 \2,'
++ sort -u
+++ grep 1 /sys/block/dm-0/removable /sys/block/dm-1/removable /sys/block/dm-2/removable /sys/block/dm-3/removable /sys/block/sda/removable /sys/block/sdb/removable
+++ sed -e 's,/sys/block/,/dev/,;s,/removable:1,*,'
++ command ls /dev/sdb /dev/sdb1
++ sed -e 's,.*\($mdir/[^ ]*\).*,\1,'
++ grep /proc/mounts

Ok, it's grep of stdin about /proc/mounts. Probably it meant to be grep for something in /proc/mounts

Indeed. In code:

    devices="$( command ls $(grep -v '^[[:space:]]*#' /etc/pmount.allow ) $(grep 1 /sys/block/*/removable | sed -e 's,/sys/block/,/dev/,;s,/removable:1,*,') 2>/dev/null | sort -u | sed -e 's,\(^/dev/\)\(.*\),\1\2 \2,' ; grep $mdir /proc/mounts | sed -e 's,.*\($mdir/[^ ]*\).*,\1,' )"

But $mdir is empty.

Solution:

maho@dlaptop:~$ diff -u /tmp/ee.pmount /etc/bash_completion.d/pmount
--- /tmp/ee.pmount      2018-05-09 14:54:34.260864752 +0200
+++ /etc/bash_completion.d/pmount       2018-05-09 14:53:31.347835234 +0200
@@ -22,7 +22,7 @@
 have pmount &&
 _pmount() {

-   local cur prev options devices fslist
+   local cur prev options devices fslist mdir

    options=' -r --read-only -w --read-write -s --sync -A --noatime -e --exec \
    -t filesystem --type filesystem -c charset --charset charset -u umask \
@@ -34,6 +34,8 @@
    cur=${COMP_WORDS[COMP_CWORD]}
    prev=${COMP_WORDS[COMP_CWORD-1]}

+   mdir="$(readlink -f /media)"
+
    case "$prev" in
       -@(t|-type))
       COMPREPLY=( $( grep "^[[:space:]]$cur" /proc/filesystems ) )

Voila!