Why does C syntax work to create variable range limit in bash?

Asked

Viewed 50 times

4

I tried to create a variable limit in a range for a for loop in bash using a function. Follow my code:

function tree(){
    let var=$1
    for i in {1..$var}
    do
        echo $i
    done
}

tree 5

To my frustration, this prints {1..5} instead of

1
2
3
4
5

I found that I can solve this problem using a syntax similar to C:

function tree(){
    let var=$1
    for ((i=1;i<$var;i++))
    do
        echo $i
    done
}
tree 6

My question is, why does the C syntax work for this case and does pure bash not work? Also, it is always possible to use C syntax in bash?

  • 1

    Very interesting question Lucas! I want to follow up if anyone knows! I was curious! great week. If you find out, put the answer here for us.

1 answer

4


If you consult the Bash manual (typing man bash in your terminal, or reading the online version), will see the following:

Brace Expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is Strictly textual. Bash does not apply any syntactic Interpretation to the context of the Expansion or the text between the braces.

That is, put variables like you did ({1..$var}) does not work at all, because in this case the $var is not interpreted as a variable.

Then one solution would be to use the for, as you did. Just to quote other solution alternatives:

# usando "seq"
function tree(){
    let var=$1
    for i in $(seq 1 $var)
    do
        echo $i
    done
}

# ou ainda (esta é mais portável, pois "seq" nem sempre pode estar disponível)
function tree(){
    let var=$1
    i=1
    while [ $i -le $var ]; do
        echo $i
        i=$(($i+1))
    done
}

As for "C syntax", it’s actually not well thus. In the same cited manual, in the section "Compound Commands", has it:

for (( expr1 ; expr2 ; expr3 )) ; do list ; done
First, the arithmetic Expression Expr1 is evaluated According to the Rules described Below under ARITHMETIC EVALUATION. The arithmetic Expression expr2 is then evaluated repeatedly until it evaluates to zero. Each time expr2 evaluates to a non-zero value, list is executed and the arithmetic Expression expr3 is evaluated. If any Expression is omitted, it behaves as if it evaluates to 1. The Return value is the Exit status of the last command in list that is executed, or false if any of the Expressions is invalid.

That is, this for is a construction defined by Bash, so you are not using "C syntax", but a syntax that Bash defined. Clear-cut which is very similar to the syntax of C (inspired? copied? ), but that’s circumstantial (I don’t know if it was "unintentional" or purposeful, but anyway it’s not C, it’s still Bash).

If I had to guess, I would say that something relatively common happened, which is when one language adopts a syntax similar (when not equal) to another (like many other languages do by adopting syntaxes similar or even identical to C).

But that doesn’t mean that any valid C syntax can be used in Bash. Some things Bash defined can be similar or identical to other languages, but still you should always consult the language manual you are using, instead of thinking "looks C, should work equal" (sometimes yes, sometimes no).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.