checkwinsize should be the default
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?
> 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
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
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
(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
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.