checkwinsize should be the default

2007-12-18 Thread ben
Configuration Information [Automatically generated, do not change]:
Machine: i486
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
-DHAVE_CONFIG_H   -I.  -I../bash -I../bash/include -I../bash/lib   -g -O2
uname output: Linux cerise 2.6.22 #3 PREEMPT Thu Dec 13 08:16:24 PST 2007 i686 
GNU/Linux
Machine Type: i486-pc-linux-gnu

Bash Version: 3.1
Patch Level: 17
Release Status: release

Description:

When an xterm is resized while a job is running, Bash does not notice
unless the shell option "checkwinsize" is set. This behavior is rarely
(never?) desirable when Bash is being used with readline editing
enabled.


Repeat-By:

Open an xterm and run bash interactively. Type a command the wraps
past the end of the line, for example:

  echo 
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

Use C-p to view the previous line in the history. Notice that the line
is printed correctly. Use C-n to clear the line.

Run a program that takes some time, such as "sleep 30", and, during
that time, use your window manager to resize the terminal window to
have more columns.

Use C-p C-p to view the line again. Notice that the text is garbled
and useless. Curse under your breath.


Fix:

Bash should default to setting checkwinsize whenever it is started
with readline editing enabled. The bash documentation need not be
updated, as it currently says nothing about checkwinsize's default
state. Question E11 can be removed from the FAQ.




Re: Recursive directory traversal?

2007-12-18 Thread Chet Ramey
> James McMurray wrote:
> > How can I recursively move through a directory tree and call a function in
> > each folder?
> 
> Mike Stroyan recently posted an example doing exactly this:
> 
>   http://lists.gnu.org/archive/html/bug-bash/2007-11/msg00080.html

There is also examples/functions/recurse in the bash distribution.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
Live Strong.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://tiswww.tis.case.edu/~chet/




Re: Please advise on programming tactics/strategy

2007-12-18 Thread Matthew Woehlke

cga2000 wrote:

I was wondering if there is any way I can convince netstat to return
its output to bash variables for processing.

Pretty simple logic:

Do forever:

  Call netstat to obtain RX & TX byte counts 
  Print delta {current .. minus previous .. byte counts}
  Save current byte counts 
  Wait for a second or so ..


I initially thought I could just pipe the "netstat -in" command to the
invocation of a bash function.

The function would have taken care of the gory details of parsing &
formatting the output of the netstat command and would then have stored
the current byte counts where they would be available for the next time
the function is invoked.

The trouble is that I haven't been able to find anything like a "static"
local variable that is not reinitialized every time the function is
invoked.


Pipes run as seperate processes, e.g. in 'somecommand | function', 
'function' is run as a subshell, so anything done in 'function' does not 
propagate up to the parent. You might want to look at bash's command 
redirection instead.


Alternatively, something like 'foo=$(netstat | extract)' where 'extract' 
filters the netstat output and condenses it down to something more 
easily parsed in the parent, e.g. 'TX:RX'. Then you can do something 
like 'tx=${foo%:*}; rx=${foo#*:}'.


--
Matthew
"Who wants to sing?" -- Orcs (Warcraft II)





Re: Segmentation fault

2007-12-18 Thread Matthew Woehlke

Chet Ramey wrote:

seba wrote:

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

#!/bin/sh

fib() {
   n=$1
   [ $n == 0 -o $n == 1 ] && return $n
   fib $(($n-1))
   ret1=$?
   fib $(($n-2))
   ret2=$?
   return $(($ret1 + $ret2))
}

for ((i=0;$i<36;i++))
do
   fib $i
   echo "n=$i=>$?"
done


You managed to write yourself an infinitely-recursive function, and
eventually ran out of stack space.  `==' is a string operator, not a
numeric operator, when used with `['.


Why is [ 0 == 0 ] any more or less true than [ 0 -eq 0 ]?

The problem seems to be that this line is missing from the function:
local n ret1 ret2

Oh, and return values wrap at 255, so using the return code only works 
up to n=13. Use substitution ($()) and have the function 'echo' the result.


--
Matthew
"Who wants to sing?" -- Orcs (Warcraft II)





Re: Segmentation fault

2007-12-18 Thread Matthew Woehlke

(things I forgot to say the first time...)
Matthew Woehlke wrote:

Chet Ramey wrote:

seba wrote:

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

#!/bin/sh


This is wrong. You're using features that are not in classic Bourne 
shell. This script will only run on /bin/sh from certain Linux 
distributions (maybe all, but I wouldn't bank on that, and certainly it 
won't run on non-Linux platforms). If you want it to run on "/bin/sh", 
you must avoid using any features not in classic Bourne. In this case, 
that means particularly $() and $(()) which are POSIX and Bash 
extensions, respectively.



fib() {
   n=$1
   [ $n == 0 -o $n == 1 ] && return $n
   fib $(($n-1))
   ret1=$?
   fib $(($n-2))
   ret2=$?
   return $(($ret1 + $ret2))
}

for ((i=0;$i<36;i++))
do
   fib $i
   echo "n=$i=>$?"
done


You managed to write yourself an infinitely-recursive function, and
eventually ran out of stack space.  `==' is a string operator, not a
numeric operator, when used with `['.


Why is [ 0 == 0 ] any more or less true than [ 0 -eq 0 ]?

The problem seems to be that this line is missing from the function:
local n ret1 ret2

Oh, and return values wrap at 255, so using the return code only works 
up to n=13. Use substitution ($()) and have the function 'echo' the result.


...which results in subshells being created, which is inefficient but 
obviates the need to use 'local' (and is therefore more portable as well).


Here's a version that should run on "/bin/sh". If you can count on using 
bash, you can make it quite a bit prettier with $() and $(()) instead of 
`'s, expr and seq.


#!/bin/sh

fib() {
   n=$1
   [ $n == 0 ] || [ $n == 1 ] && echo $n && return
   ret1=`fib \`expr $n - 1\``
   ret2=`fib \`expr $n - 2\``
   expr $ret1 + $ret2
}

for i in `seq 0 36`
do
   echo "n=$i=>`fib $i`"
done

IOW, like this:

#!/bin/bash

fib() {
   n=$1
   [ $n == 0 ] || [ $n == 1 ] && echo $n && return
   ret1=$(fib $(($n-1)))
   ret2=$(fib $(($n-2)))
   echo $(($ret1 + $ret2))
}

for ((i=0;$i<36;i++))
do
   echo "n=$i=>$(fib $i)"
done

...which only works when /bin/bash exists, of course. I haven't tried 
the first one, but the second got me to 'n=23=>28657' before I killed it 
for being slow :-).


--
Matthew
"Who wants to sing?" -- Orcs (Warcraft II)





Re: Please advise on programming tactics/strategy

2007-12-18 Thread cga2000
On Tue, Dec 18, 2007 at 09:57:44PM EST, Matthew Woehlke wrote:
> cga2000 wrote:
> >I was wondering if there is any way I can convince netstat to return
> >its output to bash variables for processing.
> >
> >Pretty simple logic:
> >
> >Do forever:
> >
> >  Call netstat to obtain RX & TX byte counts Print delta {current ..
> >  minus previous .. byte counts} Save current byte counts Wait for a
> >  second or so ..
> >
> >I initially thought I could just pipe the "netstat -in" command to
> >the invocation of a bash function.
> >
> >The function would have taken care of the gory details of parsing &
> >formatting the output of the netstat command and would then have
> >stored the current byte counts where they would be available for the
> >next time the function is invoked.
> >
> >The trouble is that I haven't been able to find anything like a
> >"static" local variable that is not reinitialized every time the
> >function is invoked.
> 
> Pipes run as seperate processes, e.g. in 'somecommand | function',
> 'function' is run as a subshell, so anything done in 'function' does
> not propagate up to the parent. 

Never does.  That's why I was looking for a way to do it via global
variables, static local variables, or .. more natural where I'm
concerned, a pointer.

> You might want to look at bash's command redirection instead.

?

> Alternatively, something like 'foo=$(netstat | extract)' where
> 'extract' filters the netstat output and condenses it down to
> something more easily parsed in the parent, e.g. 'TX:RX'. Then you can
> do something like 'tx=${foo%:*}; rx=${foo#*:}'.

Pretty much what I found.

Here's what I eventually came up with:

#!/bin/bash
interface=eth0
get_data()
{
  netstat -ni | awk '/^'"$interface"'/{print$4,$8}'   
}
read rxp txp <<< $(get_data)  
while sleep 1; do 
  read rx tx <<< $(get_data)  
  echo $((rx - rxp)) $((tx - txp)) |  
  awk '{printf "%4.1f k/s %4.1f k/s\n",$1*576/1024,$2*567/1024}'  
  rxp=$rx txp=$tx 
done
exit 0

Someone on another mailing list showed me how to use the "<<<" Here
String technique to split the output of function "get_data" into two
variables. Kinda like it better than the classic shell foo%:* etc.
Mainly because the syntax is a lot easier to remember, I guess.. the
downside is that <<< appears to be a bash-only extension and not
portable to regular Bourne sh.  Not that this matters much in this
particular case.

All in all, I'm fairly happy with this current version .. Fairly compact
and yet quite readable. 

I'm no sure about the logic of it ..  how accurate its results are.

Also, I'm definitely not too happy about the overhead .. there are idle
times on my system when this short script seems to eat up more cpu
cycles than everything else .. :-)

Maybe the next step would be to rewrite it in C.

Thanks much for your comments.