2

I have a bash script which will be called by /bin/sh on a Solaris machine. When I run the script as /bin/sh ./solarisSh, it works. When I source the same script, it fails.

I know bash and Bourne Shell are almost nothing alike. This is not my question.

My question is: Why does Solaris /bin/sh behave so differently when sourcing a file versus just plain executing a file?

Here are the data...

ns2 ~/tmp 560> env -i /bin/sh -x
$ uname -a
+ uname -a 
SunOS ns2 5.7 Generic_106541-15 sun4m sparc SUNW,SPARCstation-10
$ cat ./solarisSh
+ cat ./solarisSh 

[ ! "$BASH" ] && {
    >&2 echo "ERROR: $0 is a Bash script.  Exiting."
    return 1 2> /dev/null || exit 1
}

haveRootPriv() {
    local idCmd=/usr/bin/id
    local euid
    local uid

    [[ $OHM_OS == "SunOS" ]] && idCmd=/usr/xpg4/bin/id
    if (( ( $( $idCmd -ru) == 0 ) || ( $( $idCmd -u) == 0 ) )); then
       echo 1
       return 0
    fi
    echo 0
    return 1
}
$ /bin/sh -x ./solarisSh 
+ /bin/sh -x ./solarisSh 
+ [ !  ] 
+ echo ERROR: ./solarisSh is a Bash script.  Exiting. 
ERROR: ./solarisSh is a Bash script.  Exiting.
+ return 1 
$ . ./solarisSh 
+ . ./solarisSh 
syntax error: `$' unexpected
$ 

The ERROR: ./solarisSh is a Bash script. Exiting. is what I was expecting when I sourced the file. What I got was the syntax error: `$' unexpected.

To recap the question: Why does Solaris /bin/sh behave so differently when sourcing a file versus just plain executing a file?

I guess I have a second question, too (sorry): Why doesn't -x work when sourcing a file?

Thanks.
-Erik

1
  • It appears that sourced files are fully parsed before execution, and scripts are not. Why, I don't know, and maybe nobody does. Commented Sep 11, 2017 at 3:09

1 Answer 1

4

Deleting the $(...) command substitution removes the failure for me on 5.10. That suggests that what you're seeing is the effect of . parsing the entire file before it executes, and encountering an error at that unsupported syntax. By contrast, the script is being parsed line-by-line, so it exits before the syntax error is noticed.

Experimentally, you can insert other syntax errors and see the same behaviour: . fails early, and sh executes up to the malformed line.

Why? I don't know. It doesn't seem to be specifically documented anywhere I can find. The man page just says for .:

 . filename

     Read and execute commands from filename and return.  The
     search path specified by PATH is used to find the direc-
     tory containing filename.

The documentation for <<word says "shell input is read up to ...", which perhaps implies minimalistic parsing, but I don't see anything explicit anywhere. Line-by-line parsing is quite common for shell scripts in general, and it's what Bash does in both cases, for example.

Why doesn't -x work when sourcing a file?

It does work, as long as commands actually do start executing. Nothing is printed during the parsing phase.


For this specific example, using ` ... `-style command substitution would work, but the real script is probably more complex.

1
  • This seems to explain the behavior of both the sourcing and the -x. Rats. I was able to work around the whole mess by using an eval<<'bashScript', but the resulting script seemed both sick, and wrong. Thanks, Michael Homer, for your help understanding this matter! Commented Sep 11, 2017 at 4:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .