Question: What I have done so far is : 

```
#!/bin/bash

exec 2> >(sed 's/^/ERROR= /')

var=$(
        sleep 1 ; 
        hostname ; 
        ifconfig | wc -l ; 
        ls /sfsd; 
        ls hasdh;
        mkdir /tmp/asdasasd/asdasd/asdasd;
        ls /tmp ;
) 

echo "$var"

```

This does prepend ERROR= at the start of each error lines, but displays all errors first and then stdout, (not in order in which it was executed).

If we skip storing the output in variable and execute the commands directly, the output comes in desired order.

Any expert opinion would be appreciated.

Answer: 
The `sed` command runs asynchronously from the rest of the shell; its output goes to standard error as soon as it processes its input from the commands in the command substitution. The standard output of those commands, however, are captured in `$var` and not displayed until the `echo` command runs.

Even if you weren't capturing the output, there is a *chance* the standard error and standard output of those commands wouldn't appear as you expect, because the `sed` command that ultimately produces the error messages might not be scheduled by the OS when you expect it to be, delaying the appearance of the error messages.

When you run a command in the usual way from the terminal, that command's standard error and standard output point to the same file: the terminal itself. As such, writes to the file maintain the order in which they occur in the program. As soon as you pipe one or the other to another process, you lose all control over how the two are spliced back together, if ever. In your case, you are redirecting standard error to `sed`, which writes modified lines back to standard output. But you have no control over when the the OS schedules `sed` to run and when your shell runs, so you can't control the order in which lines are written.

It helps to redirect standard error separately for each command:

```
tag_error () { sed 's/^/ERROR= /'; }

hostname 2> >(tag_error)
{ ifconfig | wc -l ; } 2> >(tag_error)
# etc

```

but this still doesn't guarantee that writes from within the same program are ordered as if they were all writing to the same file. 

([ruakh has covered](https://stackoverflow.com/a/38947717/1126841) how to combine this with capturing standard output, so I won't bother adding it now. See his answer.)
One possible solution would be putting the commands in an array then execute them within a loop:

```
declare -a cmds=('sleep 1' 'hostname' 'eval ifconfig | wc -l' 'ls /sfsd' 'ls /tmp' 'ls hasdh')

for i in "${cmds[@]}"; do
    $i 2> >(sed -E 's/^/ERROR=/')
done

```

When an error occurs it should print in the same order that it occurred in the execution. Using a command such as `sh script.sh` within the array should also reveal any `stdout` or `stderr` from the resulting external script. For piped command an `eval` will likely be needed as well.