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