Opened 11 years ago

Closed 11 years ago

#2646 closed bug (fixed)

[ls] Multi-column output even when piped

Reported by: andreasf Owned by: axeld
Priority: normal Milestone: R1
Component: Applications/Command Line Tools Version: R1/pre-alpha1
Keywords: Cc:
Blocked By: Blocking:
Has a Patch: no Platform: All

Description

ls * | (read x && echo $x)

outputs the first entry of the first column concatenated by single whitespace with the first entry of the second column. Git expects to only get one file name from read.

Ingo said this was a problem with Haiku's read.

Change History (17)

comment:1 by emitrax, 11 years ago

Any chance this can be related to our bash version?

comment:2 by andreasf, 11 years ago

Possibly. We have GNU bash 2.05b.0(1) whereas some other OSes have 3.2.x. I also noticed our bash --version says i586-pc-beos, not i586-pc-haiku. No idea if it's easy to upgrade.

I had checked our bash's read.def but didn't spot anything obvious. Due to some comments in the code I checked whether ls * | (read && echo $REPLY) is any better, but it wasn't.

I noticed that in the home directory it's different for directories, in /boot/home/config I get Desktop: despite the second column reading apr-util. So maybe the string is just not correctly terminated?

comment:3 by anevilyak, 11 years ago

I noticed some other anomalies with our bash that may or may not be related...tab-completion of a relative path is broken, it completes the directory name and then puts a space (i.e. if I want to tab complete the path to an executable to run it).. it works correctly if you're tab completing after having typed cd first though, oddly.

comment:4 by emitrax, 11 years ago

You can try and compile bash-3.2 within haiku and check the output of the above command.

in reply to:  4 ; comment:5 by andreasf, 11 years ago

I tried, and I've come further than Scott had, but I do not get to a prompt due to issues with /etc/termcap:

http://ports.haiku-files.org/wiki/app-shells/bash/3.2/2

comment:6 by emitrax, 11 years ago

Last time I tried I did get a prompt. I'll try and builing it again today.

in reply to:  5 comment:7 by bonefish, 11 years ago

Replying to andreasf:

I tried, and I've come further than Scott had, but I do not get to a prompt due to issues with /etc/termcap:

http://ports.haiku-files.org/wiki/app-shells/bash/3.2/2

These are only warnings -- the same printed when starting the ftp client -- and shouldn't have anything to do with why you don't get a prompt.

comment:8 by bonefish, 11 years ago

I'm no longer sure that Haiku's "read" is broken. Here's what "help read" says:

read: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
    One line is read from the standard input, or from file descriptor FD if the
    -u option is supplied, and the first word is assigned to the first NAME,
    the second word to the second NAME, and so on, with leftover words assigned
    to the last NAME.  Only the characters found in $IFS are recognized as word
    delimiters.  If no NAMEs are supplied, the line read is stored in the REPLY
    variable.  If the -r option is given, this signifies `raw' input, and
    backslash escaping is disabled.  The -d option causes read to continue
    until the first character of DELIM is read, rather than newline.  If the -p
    option is supplied, the string PROMPT is output without a trailing newline
    before attempting to read.  If -a is supplied, the words read are assigned
    to sequential indices of ARRAY, starting at zero.  If -e is supplied and
    the shell is interactive, readline is used to obtain the line.  If -n is
    supplied with a non-zero NCHARS argument, read returns after NCHARS
    characters have been read.  The -s option causes input coming from a
    terminal to not be echoed.

    The -t option causes read to time out and return failure if a complete line
    of input is not read within TIMEOUT seconds.  If the TMOUT variable is set,
    its value is the default timeout.  The return code is zero, unless end-of-file
    is encountered, read times out, or an invalid file descriptor is supplied as
    the argument to -u.

"With leftover words assigned to the last NAME" is exactly what happens in Haiku. BeOS's bash 2.03 bevaves the same, while all bash 3.* versions I've tested read only the first word. So I guess updating our bash will indeed make our "read" behave the same. I suppose filing a bug report with the bash folks (that either their documentation or their implementation is wrong) would be in order.

in reply to:  8 ; comment:9 by andreasf, 11 years ago

That might explain the concatenation of the two filename columns in Git's templates subdir but not the colon after Desktop in the home dir...

Couldn't this be an issue with our POSIX (e.g., wide char) implementation?

in reply to:  9 ; comment:10 by bonefish, 11 years ago

Replying to andreasf:

That might explain the concatenation of the two filename columns in Git's templates subdir but not the colon after Desktop in the home dir...

Well, try and run an ls * in the home directory and you'll see.

in reply to:  10 comment:11 by andreasf, 11 years ago

Seems like I just did ls there for checking then, sorry. The Makefile does ls *--*, therefore ls * as simplification that appeared to work elsewhere.

If I run ls | (read x y; echo $x:$y) it separates the first and second column entries by the specified colon and then concatenates the remaining ones with whitespace, which would back your interpretation.

I checked on Solaris 10 but even that has bash 3.0 already; the only other system to cross-check I found was BeOS R5, which has 2.03.0(1), both do not expose this issue.

If it's a problem with our specific version, the question is, should we just silently upgrade to a more recent bash asap, or should we fix software like Git to handle this?

comment:12 by bonefish, 11 years ago

After some more checking, it turns out read actually behaves the same on all platforms and bash versions and according to the documentation. What does behave differently is ls. Apparently it uses a different output format when its stdout is not a tty (you can check with ls | cat), but it doesn't under Haiku. There's probably something wrong with the tty recognition, or something is misconfigured.

comment:13 by andreasf, 11 years ago

Confirmed, ls | cat is one-column elsewhere, including BeOS, but multi-column at hrev27117.

Unfortunately I don't see the ls source - it's neither in bash/builtins nor in bin.

comment:14 by emitrax, 11 years ago

you mean src/bin/coreutils/src/ls.c ?

comment:15 by andreasf, 11 years ago

Summary: [read] Too much data read[ls] Multi-column output even when piped

in reply to:  13 comment:16 by korli, 11 years ago

Replying to andreasf:

Confirmed, ls | cat is one-column elsewhere, including BeOS, but multi-column at hrev27117.

Unfortunately I don't see the ls source - it's neither in bash/builtins nor in bin.

ls uses isatty() on the stdout fd to know if multicolumns should be used.

comment:17 by korli, 11 years ago

Resolution: fixed
Status: newclosed

Fixed in hrev27421

Note: See TracTickets for help on using tickets.