Given a fish script foo.fish that only prints "foo", help, or an error
function foo
__parse_args $argv[1]
echo foo
end
function __parse_args --argument option
if test -z $option
return # No option to parse, return early
end
switch $option
case -h --help
echo "Shows this help and exits"
return 0 # How can we exit 0 instead of return?
case -\*
echo "Error: '$option' not a valid option"
return 1 # How can we exit 1 instead of return?
end
end
Actual behaviour:
↪ foo -h
Shows this help and exits
foo
Expected behaviour:
↪ foo -h
Shows this help and exits
The return manual says it stops the current inner function and sets the exit status of the function.
How can we exit the script early when inside nested function calls, with the appropriate exit code?
Note we cannot use exit because it will exit the shell instead of just the script.
Unless you run the script via source or .,it is run in its own new shell process. The exit command will terminate that process and return to the parent shell that invoked the script; the parameter to exit will be the value of $status inside that parent process immediately after the exit.
If you are actually defining the foo function in your interactive shell (via source or . or typing/pasting at your shell prompt or by defining it in your .fishrc or a startup file in ~/.config or whatever) then there is no way for __parse_args to return from foo. foo will have to check the return value of __parse_args (that is, check $status after calling __parse_args) explicitly and then return immediately if appropriate. That also means that it's up to __parse_args to return a different value when processing --help than when otherwise successful.
However, unless the actual operation of foo involves some modification to your shell environment, I would recommend making it an executable script file instead of a function, for example by putting this into a file named foo somewhere in your command search $PATH:
#!/usr/bin/env fish
function foo
__parse_args $argv[1]
echo foo
end
function __parse_args --argument option
if test -z $option
return # No option to parse, return early
end
switch $option
case -h --help
echo "Shows this help and exits"
exit 0 # How can we exit 0 instead of return?
case -\*
echo "Error: '$option' not a valid option"
exit 1 # How can we exit 1 instead of return?
end
end
foo $argv
That has the desired result:
> foo
foo
> foo -x
Error: '-x' not a valid option
[1]> foo -h
Shows this help and exits
>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With