possible compgen bug

2008-05-10 Thread Nicholas Mc Guire

HI !

problem: compgen assigns first option on receiving an empty string as
 input (i.e. by read -t 5 VAR  timing out)

systems and OS:

X86 (Duron and Sempron)

Debian etch:
[EMAIL PROTECTED]:~/shell$ uname -a
Linux backup 2.6.18-hpt374 #4 SMP Thu Mar 20 00:07:28 CET 2008 i686
GNU/Linux
[EMAIL PROTECTED]:~/shell$ bash --version
GNU bash, version 3.1.17(1)-release (i486-pc-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

Slackware 10.0:
[EMAIL PROTECTED]:~/fipsi# uname -a
Linux rtl14 2.4.26 #6 Mon Jun 14 19:07:27 PDT 2004 i686 unknown unknown
GNU/Linux
[EMAIL PROTECTED]:~/fipsi# bash --version
GNU bash, version 2.05b.0(1)-release (i486-slackware-linux-gnu)
Copyright (C) 2002 Free Software Foundation, Inc.

both systems show the same (supposedly wrong) behavior of the compgen
builtin function.


corect behavior:


when using read with a timeout and then evaluating a variable I get the
following expected behavior:

#! /bin/bash

read -p timeout 5   -t 5 CMD

if [ $CMDx == exitx ] ; then
   echo exiting
   $CMD
elif [ $CMDx == quitx ] ; then
   echo quite not a valid command calling exit with -1
   exit -1
else
   echo invalid command - exiting with -2
   exit -2
fi

which gives me the expected response when it times out due to no input

[EMAIL PROTECTED]:~/shell$ ./1.sh
timeout 5  invalid command - exiting with -2
[EMAIL PROTECTED]:~/shell$


probably errornous behavior:


when using compgen to allow shortcuts (in the below example for quit and
exit I get a strange behavior when no input is entered and write times
out after 5 seconds:

#! /bin/bash

read -p timeout 5   -t 5 FOO
CMD=( $(compgen -W quit exit -- $FOO) )

if [ $CMDx == exitx ] ; then
   echo exiting
   $CMD
elif [ $CMDx == quitx ] ; then
   echo quit not a valid command calling exit with -1
   exit -1
else
   echo invalid command - exiting with -2
   exit -2
fi

[EMAIL PROTECTED]:~/shell$ ./2.sh
timeout 5  quit not a valid command calling exit with -1
[EMAIL PROTECTED]:~/shell$

it seems to expand CMD to quit - not the behavior I expected

I assume that this is a bug in compgen as it indentifies an empty string
with the first word in the options passed - I would have expected it to be
a null-string (just as if one would type x, which has no match, thus the
null-string is assigned to CMD)

thx!
hofrat




load small history file after append breaks further appending

2008-05-10 Thread Scott Mcdermott
I've been implementing something in my shell where I'm
using multiple history files, and I switch between
them.  This changes the shell's identity, to
basically swap its history file with another.  This is being
used to have per-project histories.

The procedure I am using to switch is something like
this:

history -a  # flush anything left
history -c  # start anew
HISTFILE=newhist# prepare to load this one
history -r  # and do it (identities changed)

however I have also tried this:

history -a
history -cr newhist
HISTFILE=newhist

At this point we should be able to enter new commands,
and when we decide to, history -a (append them to the
`newhist' file).

However, bash fails to do this in the case that the new
history file is either very small, or new, i.e. zero
bytes.

I believe I have tracked down the reason this is
happening:

`bash' keeps the notion of how many lines it has
inserted into the history since the history file was
read (see `bashhist.c:history_lines_this_session').
This amount is zeroed after a successful append.

If this amount ever becomes greater than or equal to
the size of the new history that has been read (which
is what is returned from the global `history_offset' in
`history.c:where_history()'), bash will never allow the
append to succeed again (see the check on whether
history should be appended or not, which can be found
in `bashhist.c:maybe_append_history()').

BUG: This situation arises if there are a few commands
in between the successful append to the old history,
and the import of the new history, IFF the new history
is smaller than said number.

BUG: This happens also for NEW histories.  Even with a

history -cr

(resulting in `history_lines_this_session' value of `1')
instead of

history -c; history -r

(`history_lines_this_session' value of `2'), the value
is still greater than zero, which is the size of a new
history file just read, so it will NEVER work again and
all subsequent history will NOT be written with a
history -a, which silently fails to append data when
it should.

Note that on the append which occurs at shell exit,
the data WILL be appended, for two reasons:

(1) the test in `maybe_append_history()':

  history_lines_this_session  where_history()

differs from that in `maybe_save_shell_history()':

  history_lines_this_session = where_history()
 ^^

(2) the history is appended unconditionally anyways if
`force_append_history' is set (which corresponds
to `shopt -s appendhist'), whereas no such
condition is checked for in `maybe_append_history()'.

I am wondering, why not zero `history_lines_this_session'
upon a successful history -c ? As it is, clearing the
history does not change the number at all and I can
keep entering commands and clearing them all day;
`history_lines_this_session' continues to rise.  What
reason is there to keep this variable with a positive
value after all history settings are cleared? There's
nothing to write.

The following demonstrates the problem:

   $ id -un # starting as self
  smcdermott
   $ sudo -u test rm -f ~test/.bash_history # give test account
   $ sudo -u test touch ~test/.bash_history # empty history
   $ sudo su - test # become test user
   $ wc -l $HISTFILE# was indeed empty
  0 /home/test/.bash_history
   $ shopt -s histappend# force append on exit
   $ logout
   $
   $ sudo su - test # now go back and load
   $ wc -l $HISTFILE# 2 commands appended
  2 /home/test/.bash_history
   $ cp $HISTFILE $HISTFILE.new # which we stow
   $ history -a # note append works
   $ wc -l $HISTFILE
  5 /home/test/.bash_history
   $ history -cr $HISTFILE.new  # clear, load stowed 2
   $ HISTFILE=$HISTFILE.new # switch to stow file
   $ test 1 # add a few commands
   $ test 2 # that should be
   $ test 3 # appended
   $ history -a # like so
   $ wc -l $HISTFILE# but they're not
  2 /home/test/.bash_history.new

Now note when I add ONE extra command, otherwise unchanged:
---

   $ id -un
  smcdermott
   $ sudo -u test rm -f ~test/.bash_history
   $ sudo -u test touch ~test/.bash_history
   $ sudo su - test
   $ wc -l $HISTFILE
  0 /home/test/.bash_history
   $ shopt -s histappend
   $ test 1 # --- here makes 3 to save
   $ logout
   $ sudo su - test
   $ wc -l $HISTFILE
  3 /home/test/.bash_history
   $ cp $HISTFILE $HISTFILE.new
   $ history -a
   $ wc -l $HISTFILE
  6 /home/test/.bash_history
   $ history -cr $HISTFILE.new
   $ HISTFILE=$HISTFILE.new
   $ test 1
   $ 

builtin echo buffers failed writes

2008-05-10 Thread Russ Cox
This is correct (external echo):

$ /bin/echo hello world /dev/null 10
/bin/echo: write error: Bad file descriptor
$ /bin/echo goodbye world
goodbye world
$

This is not (builtin echo):

$ echo hello world /dev/null 10
bash: echo: write error: Bad file descriptor
$ echo goodbye world
hello world
goodbye world
$

The second echo printed the data that failed to get
printed by the first one!

I am using the bash preinstalled on Ubuntu Gutsy.
I have not checked whether it is fixed in later versions:

$ bash --version
GNU bash, version 3.2.25(1)-release (i486-pc-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
$

Russ Cox


Re: set -e's bug

2008-05-10 Thread Chet Ramey

Hiroshi Fujishima wrote:

Configuration Information [Automatically generated, do not change]:
Machine: i386
OS: freebsd7.0
Compiler: cc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i386' 
-DCONF_OSTYPE='freebsd7.0' -DCONF_MACHTYPE='i386-portbld-freebsd7.0' 
-DCONF_VENDOR='portbld' -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' 
-DSHELL  -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  -I/usr/local/include 
-O2 -fno-strict-aliasing -pipe
uname output: FreeBSD yamato.tonteki.org 7.0-RELEASE FreeBSD 7.0-RELEASE #0: 
Sun Feb 24 19:59:52 UTC 2008 [EMAIL PROTECTED]:/usr/obj/usr/src/sys/GENERIC 
 i386
Machine Type: i386-portbld-freebsd7.0

Bash Version: 3.2
Patch Level: 39
Release Status: release

Description:

Executing the following script.  It exits at `until command false'.


set -e
until command false; do
break
done
echo ok



Thanks for the report.  This has been fixed for the next version.

Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/




Re: Memory leak when catting(/sedding/...) large binary files with backticks

2008-05-10 Thread Chet Ramey

[EMAIL PROTECTED] wrote:

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu' 
-DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
-DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  -D_GNU_SOURCE  -O2 -g -pipe 
-Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector 
--param=ssp-buffer-size=4 -m64 -mtune=generic
uname output: Linux pmpc983.npm.ac.uk 2.6.24.4-64.fc8 #1 SMP Sat Mar 29 
09:15:49 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 3.2
Patch Level: 33
Release Status: release

Description:
Using echo `cat ...` on a large binary file causes lots of memory to be 
used (fine), but if you ctrl-c while it's running
it doesn't die properly and doesn't return used memory when finished. 
Originally found by screwing up a sed command (can
also reproduce bug using sed rather than cat) while trying to rename a 
group of files.

Repeat-By:
Every time
1. Find large binary data file for test (mine is ~3.2GB)
	2. echo `cat filename` 
	3. Ctrl-C previous command while running (doesn't terminate)

4. When step 2 eventually returns it does not release memory


I'm not sure what you mean by `doesn't return used memory', but if you mean
a process's size as reported by ps or similar, that does not indicate a
memory leak.  A memory leak is memory that has been allocated by a program
to which it retains no handles.

malloc acts as a cache between an application and the kernel.  Memory
obtained from the kernel using malloc may, under some circumstances, be
returned to the kernel upon free, but this may not always be possible.
Memory that is not returned to the kernel by freeing pages or using sbrk
with a negative argument is retained and used to satisfy future requests.

I ran your test using valgrind to check for memory leaks (but with only
a 330 MB file), and it reported no leaks after ^C.

Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/




Re: builtin echo buffers failed writes

2008-05-10 Thread Chet Ramey

Russ Cox wrote:

This is correct (external echo):

$ /bin/echo hello world /dev/null 10
/bin/echo: write error: Bad file descriptor
$ /bin/echo goodbye world
goodbye world
$

This is not (builtin echo):

$ echo hello world /dev/null 10
bash: echo: write error: Bad file descriptor
$ echo goodbye world
hello world
goodbye world
$

The second echo printed the data that failed to get
printed by the first one!

I am using the bash preinstalled on Ubuntu Gutsy.
I have not checked whether it is fixed in later versions:


This is actually dependent on your stdio implementation.  Linux versions
exhibit the above behavior, others (BSD, for example), do not.  Future
versions of bash will use fpurge(3) to make sure that stdio output
buffers are emptied when changing the underlying file descriptor.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/




Re: export -p may output invalid variables

2008-05-10 Thread Chet Ramey

Stephane Chazelas wrote:


Bash Version: 3.2
Patch Level: 33
Release Status: release

Description:
  ~$ env -i '1=a' sh -c 'export -p'
  export 1=a
  export OLDPWD
  export PWD=/home/chazelas
  export SHLVL=1
  ~$ env -i '1=a' bash -c 'export -p'
  declare -x 1=a
  declare -x OLDPWD
  declare -x PWD=/home/chazelas
  declare -x SHLVL=1
  ~$ env -i '1=a' sh -c 'export -p' | sh
  sh: line 1: export: `1=a': not a valid identifier
  ~$ env -i '1=a' bash -c 'export -p' | bash
  bash: line 1: declare: `1=a': not a valid identifier


Thanks for the report.  The right fix is to ignore words in the
environment that are not valid shell assignment statements.  Bash
already does this for words without an `=', for instance.

Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/