5

For example, if I have example.sh with following content

. non-existing.sh
echo 'continues!'

Then I source the script in an interactive session with . ./example.sh, should I see “continues!” in the terminal? The standard specifies

If no readable file is found, a non-interactive shell shall abort; an interactive shell shall write a diagnostic message to standard error, but this condition shall not be considered a syntax error.

I understand that if I . non-existing.sh the session should continues, but I’m not sure how it applies to nested sources. In Bash it continues running after printing the error message (even with set -o posix); in Dash it aborts current script (example.sh). I wonder whether this is Bash not compliant to POSIX, or is this unspecified (implementation-defined behavior) in POSIX?

Franklin Yu
  • 1,237
  • Please explain what you actually mean by "nested sources"? Do you mean a shell script which sources another shell script which in turn sources third shell script, and so on? – fpmurphy Dec 10 '20 at 07:50
  • Yes, exactly. In the example above, I sourced example.sh, which sourced non-existing.sh, so this is two-level nested. – Franklin Yu Dec 10 '20 at 07:56
  • @rowboat Then maybe it’s Dash not POSIX-compliant, always treating sourced script as non-interactive? – Franklin Yu Dec 10 '20 at 08:17
  • With this special "feature", bash is non-POSIX compliant. This has recently been discussed in the POSIX teleconference. – schily Jan 31 '21 at 14:18
  • @schily, are there any notes on that online? Just if someone would like to make a bug report – ilkkachu Feb 07 '21 at 12:47
  • IIRC, this was discussed with https://www.austingroupbugs.net/view.php?id=1384 but the long discussion is at posix.rhansen.org, you would need to search on your own. – schily Feb 18 '21 at 14:36
  • Have you tried POSIX-compliant command set -e at first? –  Feb 19 '21 at 07:39
  • @tailsparkrabbitear I know what set -e means, but it’s not required for switching to POSIX mode. I specifically don’t want errexit in this script. POSIX behavior should have been well-defined, with or without set -e. – Franklin Yu Feb 19 '21 at 17:10

2 Answers2

0

POSIX is silent about nested sourced files, but I suspect that, if an interpretation request were raised, the existing text for dot would apply.

From IEEE Std 1003.1-2017:

NAME

    dot - execute commands in the current environment

SYNOPSIS

    . file

DESCRIPTION

    The shell shall execute commands from the file in the current environment.

    If file does not contain a <slash>, the shell shall use the search path specified by PATH to find the directory containing file. Unlike normal command search, however, the file searched for by the dot utility need not be executable. If no readable file is found, a non-interactive shell shall abort; an interactive shell shall write a diagnostic message to standard error, but this condition shall not be considered a syntax error.

As regards dash or bash, there is no requirement on either shell unless they claim to to be fully conformant to IEEE Std 1003.1-2017.

Interestingly, the current dash(1) manpage on Debian Stretch contains the following text:

dash is the standard command interpreter for the system.  The current version of dash is in the process of being changed to conform with the POSIX 1003.2 and 1003.2a specifications for the shell.  ... Only features designated by POSIX, plus a few Berkeley extensions, are being incorporated into this shell.

All this manpage says about . is:

. file

    The commands in the specified file are read and executed by the shell.

As you see, dash makes no claim to conform to IEEE Std 1003.1-2017. Notwithstanding this, I postulate that the dash behavior is probably "wrong" from a standards viewpoint in that it aborts the current script rather than continuing.

fpmurphy
  • 4,636
0

If no readable file is found, a non-interactive shell shall abort

Otherwise, [if non-interactive] return the value of the last command executed — https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#dot

The 2nd quoted line suggests that the exit code of earlier commands is ignored. However I hope that if you put the shell in exit-on-error mode. Then that is what it should do.

  • If we take the example in the question, did you mean that the exit code of . non-existing.sh should be ignored, and the shell should move forward to the echo statement? – Franklin Yu Feb 07 '21 at 07:28
  • It was a long time since looking at this question. But I have just read again. I seem to be saying that the manual says that it (the default behaviour) depends on if the shell is interactive or not. – ctrl-alt-delor Feb 07 '21 at 10:12