Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Can't understand the Bash behaviour

  1. #1
    Join Date
    Nov 2014
    Location
    Kiev, Ukraine
    Posts
    68

    Default Can't understand the Bash behaviour

    Hello!

    Can't understand the Bash behaviour on such case:

    > echo $(seq -s" " 1 +2 15)

    It returns string (because -s" " is defined) of numbers: 1 3 5 7 9 11 13 15

    Now there is a simple script:

    Code:
    #!/bin/bash
    
    for n in $(seq -s" " 1 +2 15)
    do
    echo $n
    done
    
    exit 0
    It returns column of the same numbers, although -s" " is also defined.

    Can someone explain this Bash behaviour, please? :crazy:

  2. #2
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    24,869

    Default Re: Can't understand the Bash behaviour

    Instead of only telling the story that should go with the facts, why not posting the facts also:
    Code:
    henk@boven:~> echo $(seq -s" " 1 +2 15)
    1 3 5 7 9 11 13 15
    henk@boven:~> for n in $(seq -s" " 1 +2 15)
    > do
    > echo $n
    > done
    1
    3
    5
    7
    9
    11
    13
    15
    henk@boven:~>
    And I do not understand your worrying. When I do directly
    Code:
    henk@boven:~> for n in 1 3 5 7 9 11 13 15
    > do
    > echo $n
    > done
    1
    3
    5
    7
    9
    11
    13
    15
    henk@boven:~>
    that is the same. The seq tool gives you a list of numbers separated by blank spaces. And that is what is interpreted by the for construct.

    Maybe you should explain what you want to achive and not a step you took (and that might be on the wrong path to achievement).
    Henk van Velden

  3. #3

    Default Re: Can't understand the Bash behaviour

    The 'for' line is looping over everything returned from the 'seq' command,
    and then it is sending each argument to the 'echo' command, which is
    printing it; by default, echo prints something and ends it with a newline.

    It may help if you explained what you thought SHOULD happen. Want them
    all on one line? Try using 'echo -n' instead of 'echo'.

    --
    Good luck.

    If you find this post helpful and are logged into the web interface,
    show your appreciation and click on the star below...

  4. #4
    Join Date
    Nov 2014
    Location
    Kiev, Ukraine
    Posts
    68

    Default Re: Can't understand the Bash behaviour

    I'm trying to understand the logic (yes, I'm the beginner and ask beginner's questions) how Bash works. For example:

    > seq 1 +2 15

    will return the column of numbers and

    > echo $(seq 1 +2 15)

    will return the string of numbers. Why so?

    In script I wanna to achive string output after 'for... do... done' construction is worked off.

    Thanks for your help!

  5. #5
    Join Date
    Jun 2008
    Location
    Netherlands
    Posts
    24,869

    Default Re: Can't understand the Bash behaviour

    Again, please do not tell stories like doing X will return column, Bur do it on your terminal and copy/paste it here as I did. And copy/paste between CODE tags, it is the # button in the tool bar of the post editor.

    Remind that the words "string" and "column" might have different meanings in this area.

    In any case, you have a for loop and the echo inside. That means that there will be as many executions of the echo command as there are executions of the loop. And those echo command each output a line with a number. it is like you would have typed:
    Code:
    echo 1
    echo 3
    echo 5
    echo 7
    echo 9
    echo 11
    echo 13
    echo 15
    Henk van Velden

  6. #6
    Join Date
    Nov 2014
    Location
    Kiev, Ukraine
    Posts
    68

    Default Re: Can't understand the Bash behaviour

    Quote Originally Posted by hcvv View Post
    Again, please do not tell stories like doing X will return column, Bur do it on your terminal and copy/paste it here as I did. And copy/paste between CODE tags, it is the # button in the tool bar of the post editor.

    Remind that the words "string" and "column" might have different meanings in this area.

    In any case, you have a for loop and the echo inside. That means that there will be as many executions of the echo command as there are executions of the loop. And those echo command each output a line with a number. it is like you would have typed:
    Code:
    echo 1
    echo 3
    echo 5
    echo 7
    echo 9
    echo 11
    echo 13
    echo 15
    Here you are:

    Code:
    k_mikhail@linux-mk500:~> seq -s" " 1 +2 15
    1 3 5 7 9 11 13 15
    k_mikhail@linux-mk500:~> seq 1 +2 15
    1
    3
    5
    7
    9
    11
    13
    15
    k_mikhail@linux-mk500:~> echo $(seq -s" " 1 +2 15)
    1 3 5 7 9 11 13 15
    k_mikhail@linux-mk500:~> echo $(seq 1 +2 15)
    1 3 5 7 9 11 13 15
    k_mikhail@linux-mk500:~>

  7. #7

    Default Re: Can't understand the Bash behaviour

    'echo 'takes a list of arguments to be printed. It does not print exactly
    what it is given unless what it is given is quoted. You're not quoting
    the 'seq' output so it does not matter if you have one space, ten spaces,
    newlines, or tabs in there; echo will just send each thing it sees that is
    NOT whitespace (in your case, strings of digits) out in one big line.

    'for' works similarly; it cares about getting arguments which are
    delimited by whitespace; again, newline, one space, ten spaces... it
    doesn't matter. As a result, for operates on each string (of digits) as a
    single argument, and then sends it to echo. In the for-loop case, echo is
    called individually for each thing 'for' sends to it, and echo by default
    puts a newline after things it prints, so you get a "column" as you
    described it.

    --
    Good luck.

    If you find this post helpful and are logged into the web interface,
    show your appreciation and click on the star below...

  8. #8

    Default Re: Can't understand the Bash behaviour

    Quote Originally Posted by k_mikhail View Post
    Hello!

    Can't understand the Bash behaviour on such case:

    > echo $(seq -s" " 1 +2 15)

    It returns string (because -s" " is defined) of numbers: 1 3 5 7 9 11 13 15

    Now there is a simple script:

    Code:
    #!/bin/bash
    
    for n in $(seq -s" " 1 +2 15)
    do
    echo $n
    done
    
    exit 0
    It returns column of the same numbers, although -s" " is also defined.

    Can someone explain this Bash behaviour, please? :crazy:

    Hi,

    Don't loop over the command substitution because it will break if unquoted, use an array or if you really insists quote the command substitution $( ) (which is the correct way of doing it), Because of word splitting. Someone already mention that in here, or use printf as a work around.
    Quoting is often neglected in shell grammar but it is the most important part it is not just a decoration.

    Code:
    echo "$(seq -s" " 1 +2 15)"
    or

    Code:
    printf  '%d\n' $(seq -s" " 1 +2 15)
    That said seq is an external utility to the shell and you don't need it if you just want to do some counting over a loop. The cfor style for loop works with bash.

    Code:
    for ((i=1;i<=15;i+=2)); do echo "$i"; done
    Even a while loop can do that.

    Code:
    i=1; while ((i<=15)); do echo $i; ((i+=2)); done
    "Unfortunately time is always against us" -- [Morpheus]

    .:https://github.com/Jetchisel:.

  9. #9

    Default Re: Can't understand the Bash behaviour

    Quote Originally Posted by k_mikhail View Post
    Hello!

    Can't understand the Bash behaviour on such case:

    > echo $(seq -s" " 1 +2 15)

    It returns string (because -s" " is defined) of numbers: 1 3 5 7 9 11 13 15

    Now there is a simple script:

    Code:
    #!/bin/bash
    
    for n in $(seq -s" " 1 +2 15)
    do
    echo $n
    done
    
    exit 0
    It returns column of the same numbers, although -s" " is also defined.

    Can someone explain this Bash behaviour, please? :crazy:
    Hi,

    I am not a seq user but bash has nothing to do with that behaviour. Reading the seq man page it states the use of the -s flag which means.

    Code:
    -s, --separator=STRING   use STRING to separate numbers (default: \n)
    So you told seq to use a space -s " " as a separator and you expect bash to do something else .
    Since by default numbers are separated by a newline you can just do.

    Code:
    echo "$(seq 1 +2 15)"
    without the loop.
    "Unfortunately time is always against us" -- [Morpheus]

    .:https://github.com/Jetchisel:.

  10. #10
    Join Date
    Nov 2014
    Location
    Kiev, Ukraine
    Posts
    68

    Default Re: Can't understand the Bash behaviour

    Thanks to everybody - will try the variations!

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •