Q: Why `echo -n` doesn't work in this script on mac terminal? I am learning shell from tutorialspoint today:http://www.tutorialspoint.com/unix/unix-shell-loops.htm
And I copied this code block to a loop.sh file:
#!/bin/sh

a=0
while [ "$a" -lt 10 ]    # this is loop1
do
   b="$a"
   while [ "$b" -ge 0 ]  # this is loop2
   do
      echo -n "$b "
      b=`expr $b - 1`
   done
   echo
   a=`expr $a + 1`
done

But when excute it, I got things like:
...
-n 4
-n 3
-n 2
-n 1
-n 0
...

Apparently, the -n flag doesn't work in echo -n "$b ".
Then I move the same file to my Ubuntu virtual system. Runs it.
I got :
0
1 0
2 1 0
3 2 1 0
4 3 2 1 0
5 4 3 2 1 0
6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1 0

I'm confused, though Ubuntu use dash as its default sh, but OSX use official bourne shell as its sh, why the script failed here? How to fix it?

A: Echo is both a binary program (/bin/echo) as well as builtin command in some shells such as bash and sh.  As man echo states, 

 Some shells may provide a builtin echo command which is similar or iden-
 tical to this utility.  Most notably, the builtin echo in sh(1) does not
 accept the -n option.  Consult the builtin(1) manual page.


In order to fix this, you can change your script to use bash by setting the first line to 
#!/bin/bash

Or change your invocation of echo to
/bin/echo -n "$b "


A: Appending '\c' as per "man echo" documentation seemed to do this for me. So ... on line 9 the change would like below
#!/bin/sh

a=0
while [ "$a" -lt 10 ]    # this is loop1
do
   b="$a"
   while [ "$b" -ge 0 ]  # this is loop2
   do
      echo "$b \c"
      b=`expr $b - 1`
   done
   echo
   a=`expr $a + 1`
done


A: echo is not portable as you experienced. I would suggest to use the POSIX alternative printf:
printf "$b "

Note that in the general case, if you don't know in advance what contains $b, you should use instead:
printf "%s " "$b"


A: The builtin echo for /bin/sh on macOS does not support the -n option. You can use the following alternatives:
bash
Using /bin/bash works. But I don't like using it for scripts because it is not available by default for example on FreeBSD. On Linux it is available.
builtin echo and tr
If you want to use the builtin echo (e.g. when you are echoing a password and do not want to appear in ps) and want to have it more portable, you can use:
echo hello | tr -d '\n'

printf or /bin/echo
Otherwise printf or /bin/echo -n are good options, too.
Just be aware that printf takes a formatted string, so if you are including a variable in the string that might include a % or \ character, it might break things. For example:
$ w=%world ; printf "hello $w"
printf: %w: invalid directive
hello %

In such case you can use %s as format string.
$ w=%world ; printf %s "hello $w"
hello %world

\c suffix
Another option is appending \c to the end of the string when using echo (see man echo on macOS). It works fine on macOS but it's not very portable. 
