Why do I get different outputs in case of sh and bash?

sh, the Bourne shell, is old. Its behaviour is specified by the POSIX standard. If you want new behaviour, you use bash, the Bourne Again shell, which gets new features added to it all the time. On many systems, sh is just bash, and bash turns on a compatibility mode when run under that name. On Ubuntu, sh is dash, the Debian Almquist shell.

The brace expansion is a relatively new feature, and would not be available in older bashes as well. It certainly shouldn't be in sh.

The shebang line is only respected if you call the script as an executable:

./myscript.sh

I can give a script any shebang and still have it open in Python by running:

python myscript.sh

See these excellent questions on Unix & Linux:

  • Does the shebang determine the shell which runs the script?
  • Different ways to execute a shell script

SH is stupid. It can not do anything.

It only knows the most basic commands. It does not do anything else.

It can not understand {1..99} as a numeric value. It understands it as a string.

SH/Dash is not developed. It is meant to be an emergency prompt for DIRE circumstances (in interactive mode. Otherwise, it's a really good thing for scripting.).

Bash is recommended as it can do everything SH can, as well as the newest in customization and powerful features.

In answer to #1, the #! is only parsed if the program is called directly. (as in, ./program.sh)