Should errors with system() generate an error in Octave?

For version 7 (dev branch) I rationalized the behavior of many of the system-related functions such that they either throw an error or return an error code if the programmer has requested status information. The note in the NEWS file is

- Many functions in Octave can be called in a command form---no
parentheses for invocation and no return argument assignment---or in a
functional form---parentheses and '=' for assignment of return values.

    **Command Form Example**

    `mkdir new_directory`

    **Function Form Example**

    `status = mkdir ("new_directory")`

    Octave now handles errors that occur in a consistent manner.  If
    called in command form and there is a failure, an error is thrown
    and a message printed.  If called in functional form, no error or
    message is printed and the failure is communicated to the programmer
    via the output status variable.

    The following list of functions have been modified.

    * `copyfile`
    * `fcntl`
    * `fileattrib`
    * `kill`
    * `link`
    * `mkfifo`
    * `movefile`
    * `rename`
    * `rmdir`
    * `symlink`
    * `unlink`

Should the same paradigm be extended to the system() call? Right now, an error can occur but there is no immediate indication to the Octave interpreter or to the programmer. I used the following script tst_err.m

debug_on_error (1)
x = 1;
#sin ({1})
system ('abc');
disp ('past system call');

I thought when running this that the interpreter would stop and drop me in to the debugger after the system call. Instead, when running I get

sh: 1: abc: not found
past system call

It seems like it would be more intuitive if Octave emitted an error if the underlying system call had an error, unless the programmer had requested output status.

FWIW, if no output argument is requested, Matlab behaves pretty much like Octave in that it displays the error message from stderr but does not interrupt the script execution:

system ('abc');
disp ('past system call');

leads to (Matlab online, ran from linux I guess):

/bin/bash: abc: command not found
past system call

When requesting outputs, [s, msg] = system ('abc');, the stderr message is not displayed, this is a known difference with Octave, see

https://savannah.gnu.org/bugs/?44712

1 Like

The system function is probably used extensively by users (it’s at least by myself). Users will probably expect that it will be compatible with Matlab.

Regarding the entry to the NEWS file: Do you really distinguish between a function being called with command syntax versus function syntax? Is it possible to do that programmatically? Or is the deciding difference whether the functions are called with or without output argument?

It’s the latter. If the programmer has requested status output then there is no need to emit an error since an indication of failure is being returned. The predominant use case for not returning a value is command syntax. I don’t think there is a reason to change the documentation to be more specific.

Okay, I guess we can just leave this as is for now. It still makes less sense to me than throwing an error, but users get very excited when there are even slight differences in behavior between Matlab and Octave.

Yes, on the other hand I’d be happy if stderr could be redirected, as in Matlab, when requesting an output. For example [s, msg] = system ('abc'); is simple and convenient when you want to test if abc program is present, and in that case you’d like to handle error messages yourself and not let the underlying shell do it for you.

2 Likes

If I understand correctly, Matlab’s system function always joins stdout and stderr when called with two outputs and it also does not accept more than two outputs, correct? If so, then how about changing Octave to have the same behavior for two outputs, but also to provide

[status, stdout_msg, stderr_msg] = system (...)

assuming it is relatively easy to capture them separately.

This would be even better.

This could be a compatibility problem if Matlab ever decides to add a third argout to system(). It’d probably be the stderr output, but who knows?

Maybe this would be better to provide on an alternate octave.system2() function instead?

We have had to change Octave APIs several times as Matlab has embraced and extended an Octave-first idea. However, I don’t think we need to live our lives in fear of what Matlab might or might not do. It makes sense to me that stderr_msg would be the third output from system and we should just code it that way. If in the future we need to change this to introduce an osystem function with an Octave-specific API then that’s what we’ll do.

And it’s been a bummer every time, hasn’t it? I think we should live in fear of this, since it’s easy to just create separate functions in the first place. :wink:

I laughed on reading this. It’s fair to have a difference of opinion here.

On a cynical note, it won’t really matter what we call the function. If Matlab behaves like Microsoft in embracing&extending then they will still take whatever function name we come up with and re-define the API. So creating a system2 function wouldn’t be enough. Creating a function specifically in the octave namespace, for example octave.system2() as you proposed, is probably safe.

But, I don’t think it likely that Matlab is going to take the time to re-define their system call. It has been out there a long time and there is too much code that relies on it working in a certain way for them to want to tweak it just to frustrate Octave users.

I agree with you here. I’d be willing to make a fairly large bet that Matlab will never actually change the signature of system in my lifetime. :slight_smile: So this particular extension is probably safe.