« first day (4517 days earlier)      last day (448 days later) » 

1:19 PM
@terdon About *How to change the bash code to get still ... but without to use awk*,
I said: Using *pure bash* is a lot quicker for parsing small input like `xrandr` output than using (two) forks to `grep` and `tr` or `cut`.
For testing this, I've save `xrandr --current > $tempfile`. then
time for ((i=100; i--; 1))
do
    while IFS=' x+' read dev stat w h x y j _; do
        case $stat in
            connected)
                typ=sec;
                [[ $w == primary ]] && typ=${w::3} w=$h h=$x x=$y y=$j;
                break
            ;;
        esac;
    done < <(xrandr --current);
done
time for ((i=100; i--; 1))
do
    read x y < <(xrandr --current|grep -oP '\d+x\d+' | tr x ' ');
done
By using xrandr, difference are small, but pure bash is quicker.
If using a temporary file:
time for ((i=100; i--; 1))
do
    while IFS=' x+' read dev stat w h x y j _; do
        case $stat in
            connected)
                typ=sec;
                [[ $w == primary ]] && typ=${w::3} w=$h h=$x x=$y y=$j;
                break
            ;;
        esac;
    done < $tempfile;
done
time for ((i=100; i--; 1))
do
    read x y < <(grep <$tempfile -oP '\d+x\d+' | tr x ' ');
done
 
1:42 PM
Hi @F.Hauri-GiveUpGitHub and thanks for coming here! I'm afraid that is the wrong test. When you run the awk or grep commands multiple times in a shell loop, what you are seeing is that the shell loop is very slow. You are counting the time it takes to fork a new awk process in every iteration of the shell loop. That isn't a fair test since my whole point is that shell loops are slow. So yes, of course running a shell loop without forking will be faster than the same shell loop with forking.
I use this little function to time commands/scripts:
timethis ()
{
    max=$1;
    shift;
    for com in "$@";
    do
        printf 'COMMAND: %s\n' "$com";
        c=0;
        while [[ $c -lt $max ]]; do
            let c++;
            ( time -p eval "$com" ) 2>&1 | grep --color -oP 'real.*?\K[\d\.]+';
        done | awk -vm=$max '{k+=$1}END{print (k/m)}';
    done
}
It will run the specified command with time the specified number of times, and then, after the loop is done, it will print out the average time taken. Since the time command is not timing the loop but instead each execution, this isn't confused by the loop itself.
So I tried to time your script above and my xrandr --current | awk '~/\*/{print }' and, well, they're both so fast it's almost impossible! So I have to agree, the difference in speed in this specific case is completely irrelevant.
But I was never focused on the speed, as such. It's more that parsing files with bash is cumbersome and very easy to get wrong and, on top of that, it tends to be slower. Although not in this particular case (but I admit I'm still trying to figure out exactly why).
 
I agree, difference speed is not as relevant.
 
Nevertheless, I admit I am impressed at how fast that was. I think it's the case statement that really speeds things up since you're doing almost no parsing in the shell, just the split done by read and the case. .
 
Anyway, as the goal is to store values obtained from xrandr to bash variables, avoiding useless forks stay a good idea...
I was coming on ask.ubuntu, from stackoverflow.com/a/75327166/1765658.
Where I posted:
 
Is it though? I mean, as we just demonstrated, the difference in speed is negligible. So what point is there in avoiding forks if that doesn't give any significant improvement to speed and yet converts a simple, tiny pipe to a multi-line script?
 
psize=40
ar=('')
while IFS=' x+' read dev stat a b c d e f; do
if [[ $stat == connected ]]; then
typ=sec
[[ $a == primary ]] &&
typ=${a::3} a=$b b=$c c=$d d=$e
printf '%3d: %s (%s)\n' ${#ar[@]} $dev $typ
ar+=($((a*psize/100))+$((b*psize/100))+$c+$d)
fi
done < <(xrandr)
read -p 'Wich display: ' -rsn 1 userKey
if [[ ${ar[userKey]} ]]; then
geometry=${ar[userKey]}
echo $userKey
else
echo user abort
exit 1
fi
If you use a temporary file for storing xrandr output, difference become monstruous!!!
 
1:56 PM
I didn't see that at all, actually. Using a file made no discernible difference. But in any case, even if it does, then you would always have to count the time it took to write to that file as well.
@F.Hauri-GiveUpGitHub What is the input your outer while loop expects?
Ah no, it's the second that hangs. One of those recent bash changes: I only get the prompt if I enter something first.
 
getScrSize() {
    ar=('');
while IFS=' x+' read dev stat a b c d e f; do
    if [[ $stat == connected ]]; then
        typ=sec;
        [[ $a == primary ]] && typ=${a::3} a=$b b=$c c=$d d=$e;
        printf '%3d: %s (%s)\n' ${#ar[@]} $dev $typ;
        ar+=(${a}x$b+$c+$d);
    fi;
done < <(xrandr);
read -p 'Wich display: ' -rsn 1 userKey;
if [[ -n ${ar[userKey]} ]]; then
    geometry=${ar[userKey]};
    echo $userKey;
else
    echo user abort;
    exit 1;
fi;
echo $geometry
}
This ask user if more than one screen.
As the goal is to obtain **`bash` variable**, each *fork* wich could be avoided have to be avoided...
Of course, I still use `sed` or `grep` for big files!
For other thing I fight against fork every days! ;-)
I've posted an aswer to Is bash a programming language where I show some good way for doing forks...
 
2:13 PM
@F.Hauri-GiveUpGitHub But why? If, as we just demonstrated, it makes no discernible difference in the speed, what is the benefit of writing something far more complicated and harder to maintain just to avoid a few forks?
 
More flexible, more accurate and still quicker...
 
@F.Hauri-GiveUpGitHub Ah, now here we have a disagreement! :) How is bash in any way more flexible or more accurate than other tools like awk or perl?
And still quicker will need much more evidence. Yes, in this particular case it might be marginally faster, but as a general rule, parsing a file in bash will be much slower than just about any other approach you can think of.
 
Because we are already running bash, as environment.
 
OK, so?
 
Did you read my demo about mandelbrot in the answer i've previously submited?
s/read/have a look/ ;-)
 
2:19 PM
Not yet, I'm working my way through it.
Read most of it (and made an edit, sorry, I can't help it). I see a great little bash script but no arguments for why it makes more sense to write this in bash instead of another language. You even make the point that passing the iterate loop to bc instead of doing in in bash speeds things up. Which is kind of my entire point: shell loops are slow.
Don't get me wrong, I love the shell and do loads of things in it. I just wouldn't use it to parse text files with while read. Well, OK, sometimes, but rarely. It just tends to be harder to write, easier to get wrong, painful to maintain because of the annoying syntax and in 9 times out of 10 will be slower than other approaches.
And, if you take the time to optimize your bash script to make it faster, it just seems more reasonable to spend that time writing a simpler script in a more sophisticated language.
 
Of cours, I've built lot of more complex tools using perl, but now
...
Most of perl request are reduced to 1 line and rest is processed by bash...
 
Did you read through the (admittedly very long) answer I linked you to about why shell loops for parsing files is bad practice? The speed is only a tiny part of why it's a bad idea.
262
Q: Why is using a shell loop to process text considered bad practice?

cuonglmIs using a while loop to process text generally considered bad practice in POSIX shells? As Stéphane Chazelas pointed out, some of the reasons for not using shell loop are conceptual, reliability, legibility, performance and security. This answer explains the reliability and legibility aspects:...

 
I already read this
 
Do you disagree?
 
I agree with most, but not all..
 
2:26 PM
Note that the person writing it, and complaining about how hard it can be to get it right, is a world class shell expert. He's the guy who found the heartbleed bug a few years back, and you will see his name in pretty much any shell-related mailing list or reference.
 
Most of samples are base on forks and forks are resource killers
 
If even he finds the syntax hard, that is a strong argument.
 
I agree: syntax if not intutive.
For this I recommand python!
 
@F.Hauri-GiveUpGitHub Yes, but avoiding them means writing even more complex code to try and get an inherently slow tool work faster. Why not use an inherently faster tool instead.
@F.Hauri-GiveUpGitHub Yes. Or, well, anything but the shell :)
 
But for small admin, sysadmin, netadmin, shell is a must have.
 
2:29 PM
Of course!
No argument there. Especially for sysadmin stuff where execution time is very rarely a consideration.
I am not going to go and write a python or perl script to loop over a bunch of files if I only want to do it once.
So what if it takes 2 seconds to run instead of milliseconds.
 
When you try to follow/trap specific events, hires time is usefull!
I often use ${EPOCHREALTIME}, even in read -t $sleep _ because sleep implie a fork ;-)
$ toslp=00000$((1000000-${EPOCHREALTIME/.}%1000000));printf -v toslp %.6f ${toslp::-6}.${toslp: -6};read -sn1 -t $toslp _;echo ${EPOCHREALTIME}
1676039624.000108
I loose 0,1ms before echo...
Answering to you timethis() function, you could check
Where I've tried to determine how many time will take some bash builtins, like {0...999}, read from a procfile, doing a test using bash RE [[ .. =~ ..]], and some others...
 
2:59 PM
@F.Hauri-GiveUpGitHub ha! I didn't know that one, thanks! And yes, things like that, where bash has already prepopulated the variable, will always be faster, makes sense.
@F.Hauri-GiveUpGitHub ooooh, nice!
 
3:48 PM
@terdonThanks for your edition on my post!
 
4:38 PM
Sorry, I had to do work things. So, in conclusion @F.Hauri-GiveUpGitHub, I see two main take-aways here: 1) although generally slower, there are indeed cases where using the shell while avoiding forks and taking advantage of shell builtin tools/vars will be faster to run (although I am still not convinced it will be faster to code) than using other tools and 2) You know much, much more about the shell than I do! :)
 
5:16 PM
Not faster to code, not easy to read, but having to unserstand some awk syntax could by something cryptic too...
 
5:53 PM
@F.Hauri-GiveUpGitHub Yeah, I always feel a bit hypocritical when I complain about shell syntax given that I spend most of my time writing perl, awk and sed :)
 
6:14 PM
@terdon Perl is a write only language...
 
Not if you write it well! But yeah, it certainly can be.
 

« first day (4517 days earlier)      last day (448 days later) »