From 99b289474ead02cc8c629ceec1192ce9f0b4f84e Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Thu, 4 Feb 2010 16:31:51 +0200 Subject: Initial implementation of _reply_compgen_array --- contrib/mount | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/contrib/mount b/contrib/mount index d8ba81bc..c15f798f 100644 --- a/contrib/mount +++ b/contrib/mount @@ -7,6 +7,37 @@ 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 wlist + for i in ${!COMPREPLY[*]}; do + local q=`printf %q "${COMPREPLY[$i]}"` + wlist+=$(quote "$q")$'\n' + done + + # We also have to add another round of escaping to $cur. + local ecur="$cur" + ecur="${ecur//\\/\\\\}" + ecur="${ecur/#$\'/\$\'}" + + # Actually generate completions. + IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)' + + # Strip starting $' in reply if present in cur. + # This is necesarry because readline interprets everything after ' as a + # separate word for completion. + if [[ $cur == $\'* ]]; then + COMPREPLY=( "${COMPREPLY[@]/#$\'}" ) + fi +} + _mount() { local cur sm host prev @@ -48,7 +79,14 @@ _mount() elif [ $prev = -U ]; then COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*UUID=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) ) else - COMPREPLY=( $( compgen -W "$( awk '! /^[ \t]*#/ {if ($2 ~ /\//) print $2}' /etc/fstab )" -- "$cur" ) ) + COMPREPLY=() + while read -r fs_spec fs_file fs_other; do + if [[ $fs_spec = [#]* ]]; then continue; fi + [[ $fs_spec = */* ]] && { IFS=$'\0' eval "COMPRELPY+=( $'$fs_spec' )"; } + [[ $fs_file = */* ]] && { IFS=$'\0' eval "COMPREPLY+=( $'$fs_file' )"; } + done < /etc/fstab + + _reply_compgen_array fi fi -- cgit v1.2.1 From 800453c30ed0cc109b6fe4baad6094868b6646b4 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Thu, 4 Feb 2010 16:40:27 +0200 Subject: Changes line --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 106f997b..aca7bfee 100644 --- a/CHANGES +++ b/CHANGES @@ -68,6 +68,7 @@ bash-completion (2.x) * Improve ssh -o suboption completion (Alioth: #312122). * Fix NFS mounts completion (Alioth: #312285). * Fix completion of usernames (Alioth: #311396, Debian: #511788). + * Fix mount handling of escapes (Alioth: #311410, Launchpad: #219971). [ Raphaƫl Droz ] * Add xsltproc completion (Alioth: #311843). -- cgit v1.2.1 From 1096dadc26c9c4c9297a2b784e96b57e4c3bf208 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Thu, 4 Feb 2010 16:47:44 +0200 Subject: Separate _linux_fstab function --- contrib/mount | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/contrib/mount b/contrib/mount index c15f798f..b581bc27 100644 --- a/contrib/mount +++ b/contrib/mount @@ -8,6 +8,7 @@ have mount && { # Just like COMPREPLY=(`compgen -W "${COMPREPLY[*]}" -- "$cur"`), only better! +# # This will correctly escape special characters in COMPREPLY. _reply_compgen_array() { @@ -33,11 +34,29 @@ _reply_compgen_array() # Strip starting $' in reply if present in cur. # This is necesarry because readline interprets everything after ' as a # separate word for completion. - if [[ $cur == $\'* ]]; then + if [[ $cur == $\'* ]]; then #' COMPREPLY=( "${COMPREPLY[@]/#$\'}" ) fi } +# 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 + while read -r fs_spec fs_file fs_other; do + if [[ $fs_spec = [#]* ]]; then continue; fi + [[ $fs_spec = */* ]] && { IFS=$'\0' eval "COMPREPLY+=( $'$fs_spec' )"; } + [[ $fs_file = */* ]] && { IFS=$'\0' eval "COMPREPLY+=( $'$fs_file' )"; } + done + + _reply_compgen_array +} + _mount() { local cur sm host prev @@ -79,14 +98,7 @@ _mount() elif [ $prev = -U ]; then COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*UUID=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) ) else - COMPREPLY=() - while read -r fs_spec fs_file fs_other; do - if [[ $fs_spec = [#]* ]]; then continue; fi - [[ $fs_spec = */* ]] && { IFS=$'\0' eval "COMPRELPY+=( $'$fs_spec' )"; } - [[ $fs_file = */* ]] && { IFS=$'\0' eval "COMPREPLY+=( $'$fs_file' )"; } - done < /etc/fstab - - _reply_compgen_array + _linux_fstab < /etc/fstab fi fi -- cgit v1.2.1 From bfb55ddf32421ea0b0d7feb16006462b51a1a909 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Thu, 4 Feb 2010 19:02:18 +0200 Subject: (testsuite) mount.exp: Create a mount-line completion which reads from a file instead of global fstab. --- test/fixtures/mount/test-fstab | 20 +++++++++++++++++ test/lib/completions/mount.exp | 50 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/mount/test-fstab diff --git a/test/fixtures/mount/test-fstab b/test/fixtures/mount/test-fstab new file mode 100644 index 00000000..95fdd8d0 --- /dev/null +++ b/test/fixtures/mount/test-fstab @@ -0,0 +1,20 @@ +proc /proc proc defaults 0 0 +none /debug debugfs defaults,noauto 0 0 + +# Test octal escapes + +# Contains ' ' and '-' +/mnt/nice\040test\055path /dev/null auto ro,noauto 0 0 +# Contains '$' and '-' +/mnt/nice\044test\055path /dev/null auto ro,noauto 0 0 +# Contains ' ' and '\\' +/mnt/nice\040test\134path /dev/null auto ro,noauto 0 0 +# Contains '\n' and '\ ' +/mnt/nice\012test\040path /dev/null auto ro,noauto 0 0 + +# Test some labels +LABEL=Ubuntu\040Karmic /mnt/ubuntu auto no,noauto 0 0 +LABEL=Fedora /mnt/fedora auto ro,noauto 0 0 +LABEL=Debian-it's\040awesome /mnt/debian auto ro,noauto 0 0 + +#/dev/null /mnt/nice'testxxxpath auto ro,noauto 0 0 diff --git a/test/lib/completions/mount.exp b/test/lib/completions/mount.exp index 9e40803e..bcb95ba4 100644 --- a/test/lib/completions/mount.exp +++ b/test/lib/completions/mount.exp @@ -1,11 +1,38 @@ +# mount completion from fstab can't be tested directly because it +# (correctly) uses absolute paths. So we create a custom completion which +# reads from a file in our text fixture instead. +proc setup_dummy_mnt {} { + assert_bash_exec {unset COMPREPLY cur} + assert_bash_exec {unset -f _mnt} + + global TESTDIR + assert_bash_exec { \ + _mnt() { \ + local cur=$(_get_cword); \ + _linux_fstab < "$TESTDIR/fixtures/mount/test-fstab"; \ + }; \ + complete -F _mnt mnt \ + } +} + + +proc teardown_dummy_mnt {} { + assert_bash_exec {unset COMPREPLY cur} + assert_bash_exec {unset -f _mnt} + assert_bash_exec {complete -r mnt} +} + + proc setup {} { save_env -}; + setup_dummy_mnt +} proc teardown {} { + teardown_dummy_mnt assert_env_unmodified -}; +} setup @@ -30,4 +57,23 @@ assert_bash_exec {PATH="$OLDPATH"; unset -v OLDPATH} sync_after_int +assert_complete {/mnt/nice\ test-path} {mnt /mnt/nice\ test-p} +sync_after_int + +assert_complete {/mnt/nice\$test-path} {mnt /mnt/nice\$test-p} +sync_after_int + +assert_complete {/mnt/nice\ test\\path} {mnt /mnt/nice\ test\\p} +sync_after_int + +assert_complete {/mnt/nice\ test-path} {mnt /mnt/nice\ } +sync_after_int + +assert_complete {/mnt/nice\$test-path} {mnt /mnt/nice\$} +sync_after_int + +assert_complete {'/mnt/nice\ test-path'} {mnt '/mnt/nice\ } +sync_after_int + + teardown -- cgit v1.2.1 From b493869b8d4e5b2a1715d15c86dd3a3a01739299 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Thu, 4 Feb 2010 19:18:14 +0200 Subject: _reply_compgen_array: Fix leaking to environment --- contrib/mount | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/mount b/contrib/mount index b581bc27..41afb07d 100644 --- a/contrib/mount +++ b/contrib/mount @@ -17,7 +17,7 @@ _reply_compgen_array() # 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 wlist + local i wlist for i in ${!COMPREPLY[*]}; do local q=`printf %q "${COMPREPLY[$i]}"` wlist+=$(quote "$q")$'\n' -- cgit v1.2.1 From 1c4b461882c94febb39a550e0fe3065208139757 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Sun, 7 Feb 2010 01:05:51 +0200 Subject: (mount) Fix leaking fs_* vars to the environment. Explicitly save/restore IFS to be posix conformant. --- contrib/mount | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/contrib/mount b/contrib/mount index 41afb07d..bfa2a273 100644 --- a/contrib/mount +++ b/contrib/mount @@ -29,7 +29,9 @@ _reply_compgen_array() ecur="${ecur/#$\'/\$\'}" # Actually generate completions. + local oldifs="$IFS" IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)' + IFS="$oldifs" # Strip starting $' in reply if present in cur. # This is necesarry because readline interprets everything after ' as a @@ -48,10 +50,14 @@ _linux_fstab() COMPREPLY=() # Read and unescape values into COMPREPLY + local fs_spec fs_file fs_other while read -r fs_spec fs_file fs_other; do if [[ $fs_spec = [#]* ]]; then continue; fi - [[ $fs_spec = */* ]] && { IFS=$'\0' eval "COMPREPLY+=( $'$fs_spec' )"; } - [[ $fs_file = */* ]] && { IFS=$'\0' eval "COMPREPLY+=( $'$fs_file' )"; } + local oldifs="$IFS" + IFS=$'\0' + [[ $fs_spec = */* ]] && eval "COMPREPLY+=( $'$fs_spec' )"; + [[ $fs_file = */* ]] && eval "COMPREPLY+=( $'$fs_file' )"; + IFS="$oldifs" done _reply_compgen_array -- cgit v1.2.1 From 6e0dc07ee25ad9ab617ee8f5d2e861c8ef29d8bd Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Mon, 8 Feb 2010 06:52:20 +0200 Subject: (mount) Cleanup mount tests and test-fstab; fix obvious errors. --- test/fixtures/mount/test-fstab | 10 ++++++---- test/lib/completions/mount.exp | 11 +++++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/test/fixtures/mount/test-fstab b/test/fixtures/mount/test-fstab index 95fdd8d0..71036441 100644 --- a/test/fixtures/mount/test-fstab +++ b/test/fixtures/mount/test-fstab @@ -1,8 +1,10 @@ proc /proc proc defaults 0 0 none /debug debugfs defaults,noauto 0 0 -# Test octal escapes +# Simple obvious test. +/mnt/nice-test-path /dev/null auto ro,noauto 0 0 +# Test octal escapes # Contains ' ' and '-' /mnt/nice\040test\055path /dev/null auto ro,noauto 0 0 # Contains '$' and '-' @@ -13,8 +15,8 @@ none /debug debugfs defaults,noauto 0 0 /mnt/nice\012test\040path /dev/null auto ro,noauto 0 0 # Test some labels -LABEL=Ubuntu\040Karmic /mnt/ubuntu auto no,noauto 0 0 -LABEL=Fedora /mnt/fedora auto ro,noauto 0 0 -LABEL=Debian-it's\040awesome /mnt/debian auto ro,noauto 0 0 +LABEL=Ubuntu\040Karmic /mnt/ubuntu auto no,noauto 0 0 +LABEL=Fedora /mnt/fedora auto ro,noauto 0 0 +LABEL=Debian-it's\040awesome /mnt/debian auto ro,noauto 0 0 #/dev/null /mnt/nice'testxxxpath auto ro,noauto 0 0 diff --git a/test/lib/completions/mount.exp b/test/lib/completions/mount.exp index bcb95ba4..74022371 100644 --- a/test/lib/completions/mount.exp +++ b/test/lib/completions/mount.exp @@ -57,6 +57,9 @@ assert_bash_exec {PATH="$OLDPATH"; unset -v OLDPATH} sync_after_int +assert_complete {/mnt/nice-test-path} {mnt /mnt/nice-test-p} +sync_after_int + assert_complete {/mnt/nice\ test-path} {mnt /mnt/nice\ test-p} sync_after_int @@ -66,13 +69,17 @@ sync_after_int assert_complete {/mnt/nice\ test\\path} {mnt /mnt/nice\ test\\p} sync_after_int -assert_complete {/mnt/nice\ test-path} {mnt /mnt/nice\ } +assert_complete {{/mnt/nice\ test\\path} {/mnt/nice\ test-path}} \ + {mnt /mnt/nice\ } "" /@ 20 {/mnt/nice\ } sync_after_int assert_complete {/mnt/nice\$test-path} {mnt /mnt/nice\$} sync_after_int -assert_complete {'/mnt/nice\ test-path'} {mnt '/mnt/nice\ } +assert_complete {$'/mnt/nice-test-path'} {mnt $'/mnt/nice-} +sync_after_int + +assert_complete {$'/mnt/nice\ntest-path'} {mnt $'/mnt/nice\n} sync_after_int -- cgit v1.2.1 From c0b77a03f55f06fc9a00b766307335574cc79293 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Mon, 8 Feb 2010 08:35:46 +0200 Subject: (mount) Make it clear that $' strings are not supported --- contrib/mount | 12 ++---------- test/lib/completions/mount.exp | 9 ++++----- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/contrib/mount b/contrib/mount index bfa2a273..6c94e3f9 100644 --- a/contrib/mount +++ b/contrib/mount @@ -26,19 +26,11 @@ _reply_compgen_array() # We also have to add another round of escaping to $cur. local ecur="$cur" ecur="${ecur//\\/\\\\}" - ecur="${ecur/#$\'/\$\'}" # Actually generate completions. - local oldifs="$IFS" + local oldifs=$IFS IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)' - IFS="$oldifs" - - # Strip starting $' in reply if present in cur. - # This is necesarry because readline interprets everything after ' as a - # separate word for completion. - if [[ $cur == $\'* ]]; then #' - COMPREPLY=( "${COMPREPLY[@]/#$\'}" ) - fi + IFS=$oldifs } # Complete linux fstab entries. diff --git a/test/lib/completions/mount.exp b/test/lib/completions/mount.exp index 74022371..ddeadab5 100644 --- a/test/lib/completions/mount.exp +++ b/test/lib/completions/mount.exp @@ -76,11 +76,10 @@ sync_after_int assert_complete {/mnt/nice\$test-path} {mnt /mnt/nice\$} sync_after_int -assert_complete {$'/mnt/nice-test-path'} {mnt $'/mnt/nice-} -sync_after_int - -assert_complete {$'/mnt/nice\ntest-path'} {mnt $'/mnt/nice\n} -sync_after_int +# This does not work. Proper support for this requires smarter parsing of +# $COMP_LINE and it's not worth doing just for mount. +#assert_complete {$'/mnt/nice\ntest-path'} {mnt $'/mnt/nice\n} +#sync_after_int teardown -- cgit v1.2.1 From 2f61acd068a67e630dd28ce04157908398dd8798 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Mon, 8 Feb 2010 09:50:39 +0200 Subject: (mount) Make mount work properly with ' in fstab --- contrib/mount | 9 +++++---- test/fixtures/mount/test-fstab | 6 ++++-- test/lib/completions/mount.exp | 6 ++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/contrib/mount b/contrib/mount index 6c94e3f9..1896dded 100644 --- a/contrib/mount +++ b/contrib/mount @@ -19,13 +19,14 @@ _reply_compgen_array() # argument. local i wlist for i in ${!COMPREPLY[*]}; do - local q=`printf %q "${COMPREPLY[$i]}"` - wlist+=$(quote "$q")$'\n' + 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 @@ -47,8 +48,8 @@ _linux_fstab() if [[ $fs_spec = [#]* ]]; then continue; fi local oldifs="$IFS" IFS=$'\0' - [[ $fs_spec = */* ]] && eval "COMPREPLY+=( $'$fs_spec' )"; - [[ $fs_file = */* ]] && eval "COMPREPLY+=( $'$fs_file' )"; + [[ $fs_spec = */* ]] && eval "COMPREPLY+=( $'${fs_spec//\'/\047}' )"; + [[ $fs_file = */* ]] && eval "COMPREPLY+=( $'${fs_file//\'/\047}' )"; IFS="$oldifs" done diff --git a/test/fixtures/mount/test-fstab b/test/fixtures/mount/test-fstab index 71036441..b2434173 100644 --- a/test/fixtures/mount/test-fstab +++ b/test/fixtures/mount/test-fstab @@ -14,9 +14,11 @@ none /debug debugfs defaults,noauto 0 0 # Contains '\n' and '\ ' /mnt/nice\012test\040path /dev/null auto ro,noauto 0 0 +# Test apostrophe +/mnt/nice'test-path /dev/null auto ro,noauto 0 0 +/mnt/other'test\040path /dev/null auto ro,noauto 0 0 + # Test some labels LABEL=Ubuntu\040Karmic /mnt/ubuntu auto no,noauto 0 0 LABEL=Fedora /mnt/fedora auto ro,noauto 0 0 LABEL=Debian-it's\040awesome /mnt/debian auto ro,noauto 0 0 - -#/dev/null /mnt/nice'testxxxpath auto ro,noauto 0 0 diff --git a/test/lib/completions/mount.exp b/test/lib/completions/mount.exp index ddeadab5..869452b0 100644 --- a/test/lib/completions/mount.exp +++ b/test/lib/completions/mount.exp @@ -76,6 +76,12 @@ sync_after_int assert_complete {/mnt/nice\$test-path} {mnt /mnt/nice\$} sync_after_int +assert_complete {/mnt/nice\'test-path} {mnt /mnt/nice\'} +sync_after_int + +assert_complete {/mnt/other\'test\ path} {mnt /mnt/other} +sync_after_int + # This does not work. Proper support for this requires smarter parsing of # $COMP_LINE and it's not worth doing just for mount. #assert_complete {$'/mnt/nice\ntest-path'} {mnt $'/mnt/nice\n} -- cgit v1.2.1 From 4375c4b94ea7bdd370cd771aeb3483f36a42bd9f Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Tue, 9 Feb 2010 15:11:05 +0200 Subject: (mount) Split __linux_fstab_unescape function. Deal with \ at the end of strings. --- contrib/mount | 13 +++++++++++-- test/lib/completions/mount.exp | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/contrib/mount b/contrib/mount index 1896dded..e4a74372 100644 --- a/contrib/mount +++ b/contrib/mount @@ -34,6 +34,13 @@ _reply_compgen_array() 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 @@ -45,11 +52,13 @@ _linux_fstab() # Read and unescape values into COMPREPLY local fs_spec fs_file fs_other while read -r fs_spec fs_file fs_other; do + __linux_fstab_unescape fs_spec + __linux_fstab_unescape fs_file if [[ $fs_spec = [#]* ]]; then continue; fi local oldifs="$IFS" IFS=$'\0' - [[ $fs_spec = */* ]] && eval "COMPREPLY+=( $'${fs_spec//\'/\047}' )"; - [[ $fs_file = */* ]] && eval "COMPREPLY+=( $'${fs_file//\'/\047}' )"; + [[ $fs_spec = */* ]] && COMPREPLY+=("$fs_spec"); + [[ $fs_file = */* ]] && COMPREPLY+=("$fs_file"); IFS="$oldifs" done diff --git a/test/lib/completions/mount.exp b/test/lib/completions/mount.exp index 869452b0..4473c70f 100644 --- a/test/lib/completions/mount.exp +++ b/test/lib/completions/mount.exp @@ -57,6 +57,23 @@ assert_bash_exec {PATH="$OLDPATH"; unset -v OLDPATH} sync_after_int +set test "Testing internal __linux_fstab_unescape function for mount" +# One round of slashes is for bash. +assert_bash_exec {var=one\'two\\040three\\} +assert_bash_exec {__linux_fstab_unescape var} +set cmd {echo $var} +send "$cmd\r" +expect { + -ex "$cmd\r\none'two three\\" { pass $test } +# default { fail $test } +} +assert_bash_exec {unset var} + + +sync_after_int + + +# Begin testing through mnt (see setup_dummy_mnt). assert_complete {/mnt/nice-test-path} {mnt /mnt/nice-test-p} sync_after_int -- cgit v1.2.1 From 6d44b8033a2993e965c8b1fa97cba9d11fa7022e Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Mon, 15 Feb 2010 14:13:51 +0200 Subject: (umount) Parse /proc/mounts instead of mount output on Linux This makes it possible to easily unmount paths with spaces. Those are common when automatically mounting usb devices. --- contrib/mount | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/contrib/mount b/contrib/mount index e4a74372..6fbb24fa 100644 --- a/contrib/mount +++ b/contrib/mount @@ -120,12 +120,18 @@ complete -F _mount -o default -o dirnames mount have umount && _umount() { - local cur IFS=$'\n' - COMPREPLY=() - cur=`_get_cword` - COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- "$cur" ) ) + local cur=`_get_cword` + + 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 } && -- cgit v1.2.1 From 91f7e8274e90632c95527bf0fc1407e9abd0b539 Mon Sep 17 00:00:00 2001 From: Crestez Dan Leonard Date: Mon, 15 Feb 2010 15:33:10 +0200 Subject: (mount) Handle escapes in LABEL= lines from fstab. --- contrib/mount | 26 ++++++++++++++++++-------- test/lib/completions/mount.exp | 8 +++++++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/contrib/mount b/contrib/mount index 6fbb24fa..26b78ead 100644 --- a/contrib/mount +++ b/contrib/mount @@ -51,15 +51,25 @@ _linux_fstab() # 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 - __linux_fstab_unescape fs_spec - __linux_fstab_unescape fs_file if [[ $fs_spec = [#]* ]]; then continue; fi - local oldifs="$IFS" - IFS=$'\0' - [[ $fs_spec = */* ]] && COMPREPLY+=("$fs_spec"); - [[ $fs_file = */* ]] && COMPREPLY+=("$fs_file"); - IFS="$oldifs" + 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 @@ -102,7 +112,7 @@ _mount() else # probably Linux if [ $prev = -L ]; then - COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*LABEL=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) ) + _linux_fstab -L < /etc/fstab elif [ $prev = -U ]; then COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*UUID=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) ) else diff --git a/test/lib/completions/mount.exp b/test/lib/completions/mount.exp index 4473c70f..9e98cc6d 100644 --- a/test/lib/completions/mount.exp +++ b/test/lib/completions/mount.exp @@ -9,7 +9,7 @@ proc setup_dummy_mnt {} { assert_bash_exec { \ _mnt() { \ local cur=$(_get_cword); \ - _linux_fstab < "$TESTDIR/fixtures/mount/test-fstab"; \ + _linux_fstab $(_get_pword) < "$TESTDIR/fixtures/mount/test-fstab"; \ }; \ complete -F _mnt mnt \ } @@ -99,6 +99,12 @@ sync_after_int assert_complete {/mnt/other\'test\ path} {mnt /mnt/other} sync_after_int +assert_complete {Ubuntu\ Karmic} {mnt -L Ubu} +sync_after_int + +assert_complete {Debian-it\'s\ awesome} {mnt -L Deb} +sync_after_int + # This does not work. Proper support for this requires smarter parsing of # $COMP_LINE and it's not worth doing just for mount. #assert_complete {$'/mnt/nice\ntest-path'} {mnt $'/mnt/nice\n} -- cgit v1.2.1