Bash – Is the export command behaviour different in sh and in bash

bashshell

I have a shell script without the first line that specifies which shell type to use to interpret commands.

This .sh file has been used on a SCO Unix 5 system until the moment of migration on a more modern system like RHEL 7.

It seems to me that sh is the default shell in SCO Unix while the bash is the default shell in Red Hat Linux, so I think that porting the script to linux and running it, this one will be interpreted by default with the bash.

Coming to the point, in this script there is a section like this:

MY_SETUP=1
echo $MY_SETUP
MY_SETUP=2 export MYSETUP
echo $MY_SETUP

As you can see the name of the variable after the export command is not the one in the assignment (it was a typing mistake).

I noticed that the value of MY_SETUP variable after this section is different if the script is interpreted by sh or bash.

  • sh MY_SETUP value = 2

  • bash MY_SETUP value = 1

It seems that bash completely ignores the assignment inline with the export command and keeps the previous value.

All this run without returning any error, so I was wondering why there is a different behavior. Can someone explain me?

EDIT:

From Stéphane Chazelas answer it seems that in bash this instruction

var=x export var

doesn't set the "x"value and doesn't export it, but in my environment it does both. I'm confused.

Best Answer

It seems that you detected a POSIX deviation in bash that is also a deviation from the historic Bourne Shell. You may call it a bug or a just deviating behavior.

The script you refer to prints

1
2

with all shells except bash in default behavior.

If you call bash --posix, it works correctly.

From a pointer from user Kusalananda it seems that bash by default makes all builtin commands restore their temporary environment at exit and not just for the non-special builtins. Since export is a special builtin, POSIX requires a shell to behave the same as a Bourne Shell from the early 1980s end to keep the environment value.

Since bash does not implement this by default, you get the deviation.