[Bash-completion-devel] [bash-completion-Bugs][311399] DBTS 313514: bash-completion fails with e.g., ls and newlines in file names

bash-completion-bugs at alioth.debian.org bash-completion-bugs at alioth.debian.org
Wed May 16 13:43:11 UTC 2012


Bugs item #311399, was changed at 2009-01-30 12:03 by Igor Murzov
You can respond by visiting: 
https://alioth.debian.org/tracker/?func=detail&atid=413095&aid=311399&group_id=100114

Status: Open
Priority: 2
Submitted By: David Paleino (hanska-guest)
Assigned to: Nobody (None)
Summary: DBTS 313514: bash-completion fails with e.g., ls and newlines in file names  
Distribution: None
Originally reported in: Debian BTS
Milestone: None
Status: None
Original bug number: 313514


Initial Comment:
From: Anthony DeRobertis <asd at suespammers.org>
To: Debian Bug Tracking System <submit at bugs.debian.org>
Subject: bash-completion fails with e.g., ls and newlines in file names
Date: Tue, 14 Jun 2005 01:37:41 -0400

Package: bash
Version: 3.0-15
Severity: minor
File: /etc/bash_completion

anthony at bohr:foo$ touch "$(echo -e 'foo\nbar')"
anthony at bohr:foo$ ls -b
foo\nbar
anthony at bohr:foo$ ls f<tab><tab>
bar  foo  

Notice how instead of completing foo?bar (where ? = newline) it offers
to complete either foo or bar.


----------------------------------------------------------------------

>Comment By: Igor Murzov (garik-guest)
Date: 2012-05-16 17:43

Message:
Thank you for the hint. Maybe you can fix the issue yourself and submit a patch?

----------------------------------------------------------------------

Comment By: Victor Engmark (l0b0-guest)
Date: 2012-05-16 15:54

Message:
Shameless contribution of example code looping over and printing NUL-separated paths (since newlines are not printed in the web interface I'll just post the URL): https://github.com/l0b0/tilde/blob/f4263a7e0e5c436029d5d4e6b3740b28addf6dae/.bash_aliases#L43

----------------------------------------------------------------------

Comment By: Victor Engmark (l0b0-guest)
Date: 2012-05-16 15:44

Message:
Ville/Igor: `read -d $'\0'` === `read -d ''`

Igor: You might want to use `while IFS= read -d ''...` to avoid any whitespace issues.

----------------------------------------------------------------------

Comment By: Igor Murzov (garik-guest)
Date: 2012-01-25 22:22

Message:
I'm tired of trying to fix this bug :)
I thought something like:

  while read -d $'\0' -r tmp; do
    toks+=( "$tmp" )
  done <<< "$( printf '%s\0' *${xspec} )

would work fine, but it doesn't.

My (almost?) best effort is:

   # strip quote
    [[ $cur == \'* ]] && cur=${cur:1}

    if [[ "$1" != -d ]]; then
        xspec=${1:+".@($1|${1^^})"}
        # if $cur and $xspec has common part, we need to take this into account
        x=( $( printf '%s\0' @(${cur}*${xspec}|${cur%.*}${xspec} ) | \
            while read -r -d $'\0' tmp; do
                printf '%q\n' "$tmp"
            done ) )
        eval toks=( ${x[@]} ) # expand previously quoted elements
    fi

maybe this code would be useful for someone :)

----------------------------------------------------------------------

Comment By: Igor Murzov (garik-guest)
Date: 2012-01-23 02:26

Message:
Cool! Thanks!

----------------------------------------------------------------------

Comment By: Ville Skyttä  (scop-guest)
Date: 2012-01-23 01:32

Message:
read -d $'\0' appears to work for me...

----------------------------------------------------------------------

Comment By: Igor Murzov (garik-guest)
Date: 2012-01-22 21:34

Message:
`printf '%s\0' /path/to/some/where/*` is helpful and can be used in _filedir(), but `read -d '\0'` doesn't work for me and I've no idea how to make bash functions to understand '\0' :(

----------------------------------------------------------------------

Comment By: Ville Skyttä  (scop-guest)
Date: 2012-01-19 14:45

Message:
Using "find" sounds problematic to me (non-portability, possible non-availability).

Perhaps something useful would come out of something like
   printf '%s\0' /path/to/some/where/*

----------------------------------------------------------------------

Comment By: Igor Murzov (garik-guest)
Date: 2012-01-18 03:45

Message:
The problem is caused by the `compgen` command which uses '\n' as a separator for generated completions, thus 'foo\nbar' is indistinguishable from 'foo' and 'bar'. I can't see any sane way to workaround this issue reliably. The most sane fix probably is to avoid using `compgen -f` in _filedir() and use `find` or some other appropriate utility instead.

----------------------------------------------------------------------

Comment By: David Paleino (hanska-guest)
Date: 2009-01-30 12:05

Message:
From: Michael Tweedale <mpt at ic.ac.uk>
To: 313514 at bugs.debian.org
Subject: Re: bash-completion fails with e.g., ls and newlines in file names - workaround
Date: Thu, 18 May 2006 12:29:44 +0100

Package: bash
Version: 3.1-4
Followup-For: Bug #313514

On  8 Nov 2005 at 11:29, Mike Dornberger wrote:
> Interesting point is, that it _only_ seems to break on 
> newlines.

It also chokes on filenames with an equals sign:
$ touch x=y
then
$ ls x<TAB>
completes correctly;
$ ls x=<TAB>
completes (bizarrely) to x=x\=y and
$ x=<TAB>
as expected completes to a list of all filenames in cwd 
(though if . is in $PATH maybe it should complete to x=y ?).

Best,
Michael

----------------------------------------------------------------------

Comment By: David Paleino (hanska-guest)
Date: 2009-01-30 12:04

Message:
From: Mike Dornberger <Mike.Dornberger at gmx.de>
To: Debian Bug Tracking System <313514 at bugs.debian.org>
Subject: Re: bash-completion fails with e.g., ls and newlines in file names - workaround
Date: Tue, 8 Nov 2005 11:29:30 +0100

Package: bash
Version: 2.05b-26
Followup-For: Bug #313514

Hi,

this bug hit me today, too, when I wanted to delete filenames with
newlines.

Completion for mv, rm and ls (haven't tested others) show this bug, even if
you use M-* (insert-completions).

$ rm fo<M-*>

results even to:

$ rm bar foo 

It does not fail on e. g. echo:

$ echo fo<tab>

$ echo 'foo
bar' 

(M-* works here correctly, too.)

Interesting point is, that it _only_ seems to break on newlines. Doing

$ touch "$(echo -e 'evil filename with\nan LF and other special chars ($bla) : , "')"
$ rm ev<M-*>

results in:

$ rm an\ LF\ and\ other\ special\ chars\ \(\$bla\)\ \:\ \,\ \" evil\ filename\ with 

As a little workaround one can either write

$ echo rm ev<tab>

or

$ xrm ev<tab>

then using C-a or Home and deleting "echo " or "x" before execution. The
last one maybe only works if there isn't a xrm file/function/alias or
something. And oh, I just found out, you can even do

$ rm ev<M-/>

(M-/ is by default bound to complete-filename. M-x BTW can be entered as ESC
x, too.)

Greetings,
 Mike


----------------------------------------------------------------------

You can respond by visiting: 
https://alioth.debian.org/tracker/?func=detail&atid=413095&aid=311399&group_id=100114



More information about the Bash-completion-devel mailing list