You are not logged in.

#1 2022-05-20 18:06:07

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

[SOLVED] bash nested loops

hi scripters of bash

Does anybody know if there is any way to find the number of the depth of loops in a script. What I want to do is be able to break to the outside loop regardless of depth. Unfortunately break does not support -1. I can't find a bash variable for this (unlike function calls), and as far as I can see  bash runtime keeps hard line addresses for loop control, which, I might add, is a goto by any other name. Of course, if we still had goto then this would not be a problem, but that's a whole new story. Thanks one and all.

Last edited by olly (2022-05-22 10:30:05)


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#2 2022-05-20 20:06:01

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,230
Website

Re: [SOLVED] bash nested loops

There are lots of approaches - can you share the code so we can see what you're working with?  Likely the simplest would be to use an arbitrarily high value to "break".

EDIT: I may have mis-read: do you want to break out of the outtermost loop, or break out of all except the outtermost?  In the case of the latter, one option is to track depth yourself.  Set a variable that gets incrememented before the start of each loop and decremented after the loop ends.  Though I suspect there are cleaner solutions with some refactoring: put the content of the outer loop in a function and call that function in a loop, then any loop within the function (regardless of depth) can call "return" to go back to the outter loop.

EDIT: Actually if the goal is to break to the outtermost loop, then "continue" with an arbitrarily high parameter could work assuming the nested loops you break out of are at (or can be moved to) the end of the outter loop.

Last edited by Trilby (2022-05-20 20:50:35)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3 2022-05-20 21:20:53

seth
Member
Registered: 2012-09-03
Posts: 57,061

Re: [SOLVED] bash nested loops

You could also add a flag ("breaktosurface=true") and condition the break on the intermediate loops on that.

Offline

#4 2022-05-21 13:02:39

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

Thanks for replies.

Counting loop depth and breaktosurface are good, but in practice there are so many the overhead is greater than hardcoding break -number. Putting it in one control loop function works, but within the loop are many others, so you would have to count the returns as well.

I'm dealing with lines in a file, with the outer loop fixed on a line number, and inner loops allowing the user to edit fields in the line, move to another line, or exit the program, amongst many other things. Structured programming  has its benefits, but on large programs trying to find which if belongs to which else and fi, is more trouble than it's worth, and, if then two lines of code, else two hundred lines of code, disproportionately effects style. Using mostly functions can work, but does not allow no return calls. So I invented the bash goto.

line=1
goto=display-line

while : ; do
while : ; do

goto ()  { goto=$1 ; }

case "${goto}"  in

select-option) select forward/backward/edit/quit
           goto ${ selection} 
           break ;;

forward) line=line+1
                goto display-line
                break ;;

backward) line=line-1
                    goto display-line
                    break ;;

display-line) display line on screen
         .             goto select-option
                       break ;;

edit-line) edit line with lots of loops
                goto select-option
                break ;;

exit) break 2 ;;

done
done

And it's clean, simple and very fast, except the single fact that in, for example, the edit code block with lots of loops, you can't just break to the outer loop simply. Also you can't include the break function within the goto function, making it not possible to just use a single goto command.


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#5 2022-05-21 13:37:21

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 257

Re: [SOLVED] bash nested loops

olly wrote:

I'm dealing with lines in a file, with the outer loop fixed on a line number, and inner loops allowing the user to edit fields in the line, move to another line, or exit the program, amongst many other things.

For me it smells like a state machine. Operations are already split into blocks. Just let each block return which block should run next.

Offline

#6 2022-05-21 14:35:57

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,230
Website

Re: [SOLVED] bash nested loops

I asked for the code to see what your goal was, and you shared very broken pseudo-code that requires absolutely nothing of what you asked about?  I suspected this was an X-Y problem, but now it's now sounding like a (problematic) solution in search of a problem.  You seem to be trying to write bad code just to justify the use of a bad not-really-a-goto goto function.

If you want help writing good code, tell us the actual goals.

FWIW, that pseudo-code could be done without any gake "goto" gymnastics (not to mention the effectively no-op function which has the same name as a variable):

#!/bin/bash

line=1

select cmd in forward backward edit quit; do

case $cmd in
	forward) line=$((line+1)) ;;
	backward) line=$((line-1)) ;;
	edit) #TODO: edit line with lots of loops
		continue ;;
	quit) break ;;
esac

# TODO: display line on screen
echo $line # placeholder

done

Last edited by Trilby (2022-05-21 14:37:26)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#7 2022-05-21 14:47:24

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

Dimich wrote:

For me it smells like a state machine. Operations are already split into blocks. Just let each block return which block should run next.

In a single state, and I'm assuming you mean, in bash, run each block in a function, with a return value. In simple cases I would agree, and the example I gave is very simplified. In some cases it is preferable to call non return functions. Consider my example, but control goes to the edit line function, within which control is selected by means of a call to a text edit function, that can be either an edit of the line components itself, or a call to another function (up arrow) at any time in the line edit function. You already have function return nesting of three levels, each requiring a test for certain values. Why introduce unesessary overheads when at any point you can jump directly to the next function. I'm a believer that different problems call for different programming paradigms, and when you start designing in unessesary
complexity solving code, then the paradigm is wrong.

Last edited by olly (2022-05-21 15:09:17)


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#8 2022-05-21 15:01:35

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,230
Website

Re: [SOLVED] bash nested loops

olly wrote:

I'm a believer that different problems call for different programming paradigms

Which is why we need to know what actual problem you are working on, not a completely artificial example made up in order to require the "paradigm" you seem set on using.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#9 2022-05-21 15:03:15

seth
Member
Registered: 2012-09-03
Posts: 57,061

Re: [SOLVED] bash nested loops

In simple cases I would agree, and the example I gave is very simplified. In some cases it is

Trilby wrote:

I asked for the code to see what your goal was

Unless there're legal reasons prohibiting it, I'd suggest that's what you should do.
You original inquiry was "What I want to do is be able to break to the outside loop regardless of depth" but your example is just an event loop emulation in spaghetti code that could easily be replaced by proper function calls and that leaves everyone puzzled about the task, the goal and the sensibility of your approach.

Offline

#10 2022-05-21 15:31:44

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

Seth wrote:

I asked for the code to see what your goal was

No, there is no legal reason or reticence on my behalf. It's simply that the code is over a thousand lines long, so I demonstrate with pseudo (spaghetti) code. It's the structural concept (paradigm) I'm showing, which I believe is much cleaner, simpler and faster than other structures. It is not a request for programming lessons, I'm simply trying to find if there is a loop counter similar to function history array in bash. I'm not sure why everyone is aggressive, it's just a request about a detail of bash.


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#11 2022-05-21 15:41:04

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,230
Website

Re: [SOLVED] bash nested loops

olly wrote:

It is not a request for programming lessons, I'm simply trying to find if there is a loop counter similar to function history array in bash.

No, there isn't.  Please mark the thread as SOLVED.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#12 2022-05-21 15:43:27

seth
Member
Registered: 2012-09-03
Posts: 57,061

Re: [SOLVED] bash nested loops

Nobody's aggressive, just confused.
You could move the code to github or a pastebin service.
1000 LOCs isn't much to just understand the issue you're facing (you're not asking to proof-read it or find a typo)

pseudo (spaghetti) code […] I believe is much cleaner, simpler and faster than other structures

I'd meditate about that…

Offline

#13 2022-05-21 15:56:25

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

seth wrote:

pseudo (spaghetti) code […] I believe is much cleaner, simpler and faster than other structures
I'd meditate about that…

Not that pseudo code is. My proposition is that structured programming and/or functional programming might not be be as appropriate as other structures in some cases, including the use of goto  to mitigate complexity.

Last edited by olly (2022-05-21 16:01:47)


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#14 2022-05-21 16:00:29

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,230
Website

Re: [SOLVED] bash nested loops

olly wrote:

My proposition is that structured programming and/or functional programming might not be be as appropriate as other structures in some cases

1) Of course that's true, now stop trolling trying to get someone to disagree with you an a point that as likely true as it is vacuously meaningless.
2) But who cares?  You explicitly said this thread is not to discuss these points but only to get a concrete answer to a simple yes or no question.  You have your answer.  Mark the thread as solved.

Last edited by Trilby (2022-05-21 16:01:27)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#15 2022-05-21 16:17:06

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

Trilby wrote:
olly wrote:

My proposition is that structured programming and/or functional programming might not be be as appropriate as other structures in some cases

1) Of course that's true, now stop trolling trying to get someone to disagree with you an a point that as likely true as it is vacuously meaningless.
2) But who cares?  You explicitly said this thread is not to discuss these points but only to get a concrete answer to a simple yes or no question.  You have your answer.  Mark the thread as solved.

I'm not sure that everyone on a forum specifically for arch users and computer scientists would agree that a debate about the fundamentals of programming is "vacuous". It might also be the case that although you don't know of such a bashism,  others might.


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#16 2022-05-21 16:27:53

seth
Member
Registered: 2012-09-03
Posts: 57,061

Re: [SOLVED] bash nested loops

Not a debate, but your statement.
"Sometimes something is better than another thing" is not debatable but self evident by its vagueness.

If your "structure" is indeed 1000+ spaghetti LOCs it's not "cleaner, simpler" and "faster" is something one doesn't have to "believe" but can just profile - and otherwise the example isn't representative of the problem.

Also, for your "bashism":

loop counter similar to function history array

is nonsense.
A counter (of any kind) is not an array.
I'm not sure what a "loop counter" is supposed to be, but google thinks I'm referring to the iterator which would be irrelevant to the previous discussion.
And I don't see at all how a function history would help with any of the suggested situations.

So how you want to have a "loop counter" that's similar to a "history array" is beyond me and reason - it doesn't exist because it cannot exist.
If you want to keep an array of anything, that's of course possible and if you want to somehow belong to your loops you'd just feed it at the beginning or end of each of your loops (depending on what you actually want to do - what we don't know)

I start to agree w/ Trilby that this thread is mostly an exercise in trolling…

Offline

#17 2022-05-21 16:43:59

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,230
Website

Re: [SOLVED] bash nested loops

olly wrote:

I'm not sure that everyone on a forum specifically for arch users and computer scientists would agree that a debate about the fundamentals of programming is "vacuous".

And I never said it was.  But 1) this is not what you introduced, and 2) you specifically said you didn't want this sort of discussion!  You just want an answer to your yes or no question.

olly wrote:

It might also be the case that although you don't know of such a bashism,  others might.

So you asked a yes or no question, but you determined in advice which of those two answers you'd accept?

There is no hidden feature for this.  And while I will readily admit there is always more I can learn, I know shell scripting pretty well (and you clearly don't), so I am quite confident in my answer that there is no current bash builtin / variable to determine the loop depth.  If you don't like this answer, too bad, it's still true.  If you want this to change, take it up with the gnu/bash dev team as a feature request ... be sure to show them your pseudo-ghetti code, they might enjoy the laugh.

Last edited by Trilby (2022-05-21 16:46:25)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#18 2022-05-21 17:00:47

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

Olly wrote:

My proposition is that structured programming and/or functional programming might not be be as appropriate as other structures in some cases

Seth wrote:

Not a debate, but your statement.
"Sometimes something is better than another thing" is not debatable but self evident by its vagueness.

Not that vague.

Seth wrote:

loop counter similar to function history array

So how you want to have a "loop counter" that's similar to a "history array" is beyond me

Is there not an environmental variable within a shell script in the form of a array called something like $FUNCTION that holds a history of function calls, which, by the number of elements, gives the depth of functions. If so, could not the same be done for nested loops,?

Last edited by olly (2022-05-22 14:20:59)


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#19 2022-05-22 10:28:51

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

dimich wrote:

For me it smells like a state machine. Operations are already split into blocks. Just let each block return which block should run next.

Hi Dimich,
Thank you for a positive contribution. You might be a student, or not, but if you are interested in state machine processing please explore (if you have not done so) the State Space Search of single instance in infinite states, and have a go at The Two Jug Problem. I wish you all the best. Our thoughts and prayers are with you.


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#20 2022-05-22 19:04:19

seth
Member
Registered: 2012-09-03
Posts: 57,061

Re: [SOLVED] bash nested loops

Is there not an environmental variable within a script in the form of a array called something like $FUNCTION that holds a history of function calls, which, by the number of elements, gives the depth of functions. If so, could not the same be done for nested loops?

#!/bin/bash

foo() {
    printf "SNA"
}
bar() {
    printf "FU\n"
}
foo; bar
[ -z ${FUNCTION} ] && echo "Doesn't seem so..."

If you mean the "history" function, that's a shell specific implementation (most likely as stack in C) and while you could just wrap your loops into functions to get there then I still don't see how logging functions/loops would relate to anything in this thread…

Offline

#21 2022-05-22 19:17:11

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

seth wrote:

Is there not an environmental variable within a script in the form of a array called something like $FUNCTION that holds a history of function calls, which, by the number of elements, gives the depth of functions. If so, could not the same be done for nested loops?

#!/bin/bash

foo() {
    printf "SNA"
}
bar() {
    printf "FU\n"
}
foo; bar
[ -z ${FUNCTION} ] && echo "Doesn't seem so..."

If you mean the "history" function, that's a shell specific implementation (most likely as stack in C) and while you could just wrap your loops into functions to get there then I still don't see how logging functions/loops would relate to anything in this thread…

"${FUNCNAME[@]}"

return $(("${#FUNCNAME[@]}"-1))

break $(("${#LOOPNAME[@]}"-1))

Last edited by olly (2022-05-22 19:36:21)


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#22 2022-05-22 19:41:34

seth
Member
Registered: 2012-09-03
Posts: 57,061

Re: [SOLVED] bash nested loops

We can try this w/ a lot of variables…

#!/bin/bash
foo() {
    printf "SNA"
}
bar() {
    printf "FU\n"
}
foo; bar
echo ${FUNCNAME[@]}
[ -z ${FUNCNAME} ] && echo "Doesn't seem so..."

It does this here:

#!/bin/bash
foo() {
    echo "${FUNCNAME[@]}"
    printf "SNA"
}
bar() {
    printf "FU\n"
    echo "${FUNCNAME[@]}"
    foo
}
foo; bar
echo "${FUNCNAME[@]}"
[ -z ${FUNCNAME} ] && echo "Doesn't seem so..."

*Inside* a function - which seems to contradict the premise of your task.
Also, how do you want to identify the loop?
And while I still don't understand how this would help you (and blatantly assume it won't), you can really just head and tail every loop by in-/decrementing a counter.
Or use functions…

Offline

#23 2022-05-23 10:24:24

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

Try

clear

function_one {
echo "I am in function ${FUNCNAME[0]} with a depth of ${#FUNCNAME[@]}" 
}
function_two {
echo "I am in function ${FUNCNAME[0]} with a depth of ${#FUNCNAME[@]}"
function_one
}
function_three {
echo "I am in function ${FUNCNAME[0]} with a depth of ${#FUNCNAME[@]}"
function_two
}
for function in one two three ; do
echo -----
function_"${function}"
done

Inside a function - inside a loop, that's the point.

There is no need to name loops, just count them.

Counting in and out of loops is an overhead and prone to errors when code is modified, which would become completely unnecessary with this feature.

I absolutely know this would help me.

As to why not just use functions? This  is a larger question and has been an ongoing debate for a long time. It generally comes down to unrestricted code block execution and jumps. Google about the goto statement and structured programming / functional programming, there is a lot of literature about this on line. Is is noticeable, however, that quite an number of languages have reintroduced the goto statement, while bash has not. It's an interesting subject.

Last edited by olly (2022-05-23 10:28:27)


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

#24 2022-05-23 13:34:18

seth
Member
Registered: 2012-09-03
Posts: 57,061

Re: [SOLVED] bash nested loops

Try

I knwo how that variable works.

Counting in and out of loops is an overhead and prone to errors when code is modified, which would become completely unnecessary with this feature

You already opted for spaghetti code…

#!/bin/bash

shopt -s expand_aliases

alias until='((loopdepth++)); until'
alias while='((loopdepth++)); while'
alias for='((loopdepth++)); for'
alias done='done; ((loopdepth--))'

loopdepth=0
for ((i=0;i<1;++i)); do
    echo "for $loopdepth"
    while ((i<1)); do
        echo "while $loopdepth"
        until ((i>0)); do
            ((++i))
            echo "until $loopdepth"
        done
        echo "while2 $loopdepth"
    done
    echo "for2 $loopdepth"
done

Google about the goto statement

https://i.imgur.com/4t2IduB.jpeg

Offline

#25 2022-05-23 14:48:15

olly
Member
From: South West England
Registered: 2017-08-22
Posts: 38

Re: [SOLVED] bash nested loops

Thank you!.

You have precisely made my point for me!

That is exactly the type of "work around" and overhead code that needs to be introduced to achieve a simple goal. Coding shows that if there is, at any time, a need to compensate for inadequacies in a structure, then the structure should be adapted. When I say Google the goto statement, I mean have a look at Wikipedia and get an understanding of the idea, particularly the introduction of the structured programming paradigm. As I have said before, many other languages have reintroduced it, some by emulation which is what I'm looking at. Bash is an evolving language, and an inbuilt loop counter would move toward that. It's not about out clevering each other, it's the bigger picture. I started this thread not just to ask about a loop counter, but to also maybe start a intelligent debate about the use of, and possible reintroduction in bash, of the goto statement. I thought the arch forum might be a place to do this. Try and prove me right.


Bullies are only weak people trying to compensate for their own inadequacy. If they can't compete intellectually, they bully.

Offline

Board footer

Powered by FluxBB