![]() |
ubuntu.com - launchpad.net - ubuntu help
|
|
|||||||
|
Programming Talk This forum is for all programming questions. The questions do not have to be directly related to Ubuntu and any programming language is allowed. |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
5 Cups of Ubuntu
![]() Join Date: Apr 2005
Location: Luxembourg
Beans: 44
|
ksh vs bash: setting variable in piped loops are lost
I'm a long time unix (not linux) programmer, mainly shell scripts.
Unix does not know about bash, but rather ksh or sh. So I often build stuff like this: Code:
n=0
du | sort -n | while read size dir
do
if [ "$size" -gt 100000 ]
then
n=$((n+1))
fi
done
echo "Found $n too big files"
The question is: in ksh this script returns the correct value in bash it always returns 0 This is because in ksh the last command in the pipe runs in the current process, whereas in bash the first command runs in the current proces. Result: the modified variables are lost. I'm still puzzled that his is the case and that nobody really cares about. Maybe I'm missing the point and there is some simple environment variable or other setting to change to enable ksh compatible behaviour. Georges |
|
|
|
|
|
#2 | |
|
I Ubuntu, Therefore, I Am
![]() |
Re: ksh vs bash: setting variable in piped loops are lost
Quote:
I suppose a bash kludge could be to use tmp files rather than a pipeline, but that isn't very elegant.
__________________
What's a blub programmer? Registered Linux user #419974 My projects: |
|
|
|
|
|
|
#3 |
|
5 Cups of Ubuntu
![]() Join Date: Apr 2005
Location: Luxembourg
Beans: 44
|
Re: ksh vs bash: setting variable in piped loops are lost
yes, "apt-get install ksh" is a solution too.
So you never use longer pipe constructs with loops etc? That's the real power of shell programming, else one could as well use perl. zsh also behaves correctly. Only bash is different. The developers probably think they can reinvent the wheel in square form. Do you think there is any chance that a bug report will help? |
|
|
|
|
|
#4 | |
|
100% Pure Ubuntu
![]() Join Date: May 2006
Beans: 852
|
Re: ksh vs bash: setting variable in piped loops are lost
Quote:
|
|
|
|
|
|
|
#5 |
|
First Cup of Ubuntu
![]() Join Date: Mar 2007
Beans: 1
|
Re: ksh vs bash: setting variable in piped loops are lost
I know this is a dead thread but I wanted to add something in case someone comes looking at this for a solution. My thanks as always to the mksh team. The solution involves (m)ksh co-processes. Sounds like you may be able to do something similar with bash using named pipe pairs (one for read, one for write) if you do a little research in that area.
This works in mksh 35b: Code:
n=0
du | sort -n |&
while read -p size dir
do
if [ "$size" -gt 1000 ]
then
n=$((n+1))
fi
done
echo "Found $n too big files"
|
|
|
|
|
|
#6 |
|
5 Cups of Ubuntu
![]() Join Date: Apr 2005
Location: Luxembourg
Beans: 44
|
Re: ksh vs bash: setting variable in piped loops are lost
that's like a kludge with temporary files we mentioned earlier.
And there are no co-processes in bash either. How can this be the default shell in linux. It lacks several great inventions which make unix stand out. Thanks for the hint on mksh, I will give it a try (setting it as default shell). Georges |
|
|
|
|
|
#7 | |
|
Spilled the Beans
![]() Join Date: Nov 2008
Beans: 13
|
Re: ksh vs bash: setting variable in piped loops are lost
That would be me
Quote:
Code:
(du | sort -n) |& Last edited by mirabilos; November 12th, 2008 at 05:32 PM.. Reason: typo |
|
|
|
|
|
|
#8 |
|
Dipped in Ubuntu
![]() Join Date: Jul 2008
Beans: 565
|
Re: ksh vs bash: setting variable in piped loops are lost
I just spent 15 minutes trying to do this in pure bash before realizing that this thread is nearly 2 years old.
Anyway, here's what I came up with. It's not pretty, but it works.Code:
#!/bin/bash
n=0;a=0;x=0
for line in `du | sort -n`;do
if [ $line -eq $line 2> /dev/null ];then
size[$n]=$line
n=$(($n+1))
fi
done
while [ $x -lt ${#size[*]} ];do
if [ ${size[$x]} -gt 100000 ];then
a=$(($a+1))
fi
x=$(($x+1))
done
echo "Found $a too big files"
exit
__________________
Code:
clear;while read x;do for((i=0;i<${#x};i++));do printf "${x:$i:1}";sleep .015;done;echo;done< <(awk '/[<\/li>,<ul>]<li>/{gsub(/<[^<]*?\/?>|\[.*\]|\(.*\)/,"");$1=$1;print}' <(wget -q -O- http://bit.ly/zDZ1I))
|
|
|
|
|
|
#9 |
|
Dipped in Ubuntu
![]() Join Date: Sep 2007
Location: Cambridge, MA
Beans: 534
|
Re: ksh vs bash: setting variable in piped loops are lost
Unfortunately bash is plain and simply correct when it comes to bourne shell script according to POSIX. You got the pipe, you are in a child process and nothing you do influences the parent process.
This is really annoying since it pretty much disables all sane ways to deal with filenames that contain any number of wired characters, sequences of multiple spaces one after another etc. You never can use find . ... | while read foo ; echo $foo ; do Nor can you use find . -print0 | xargs -0 ... invoking anything under the script's control that would allow you to count. The only way to make use of this in the loop solution is to return everything you want for status by echoing them and putting the whole loop into $(...). If you need stdout for other purposes inside the loop you gotta start placing a bunch of bloddy `1>&3) | ... 3>&1 | grep`. |
|
|
|
|
|
#10 |
|
I Ubuntu, Therefore, I Am
![]() Join Date: Feb 2007
Beans: 3,453
Ubuntu 9.04 Jaunty Jackalope
|
Re: ksh vs bash: setting variable in piped loops are lost
I guess the prettiest way to handle it in bash would be something like this:
Code:
#!/bin/bash exec 3< <(du | sort -n) n=0 while read size dir; do [ $size -gt 1000 ] && ((n++)) done <&3 exec 3<&- echo "Found $n too big files" |
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|