如何从较低级别的函数中止鱼脚本?

Den*_*nis 5 shell return abort fish

给定一个foo.fish只打印“foo”、帮助或错误的鱼脚本

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
Run Code Online (Sandbox Code Playgroud)

实际行为:

? foo -h
Shows this help and exits
foo
Run Code Online (Sandbox Code Playgroud)

预期行为:

? foo -h
Shows this help and exits
Run Code Online (Sandbox Code Playgroud)

该return手册称,停止当前的内部功能和设置功能的退出状态。

在嵌套函数调用中,我们如何使用适当的退出代码提前退出脚本?

注意我们不能使用,exit因为它会退出 shell 而不仅仅是脚本。

Mar*_*eed 5

除非您通过source或运行脚本,否则.它会在自己的新 shell 进程中运行。该exit命令将终止该进程并返回到调用该脚本的父 shell;参数 toexit将是$status退出后立即在该父进程内的值。

如果您实际上是foo在交互式 shell 中定义函数(通过source或.或在 shell 提示符下键入/粘贴,或通过在 .fishrc 或 ~/.config 中的启动文件或其他任何文件中定义它),则无法__parse_args返回从foo. foo将必须显式__parse_args检查(即$status在调用后检查)的返回值,__parse_args然后在适当的情况下立即返回。这也意味着__parse_args在处理--help时返回一个与其他成功时不同的值。

但是,除非实际操作foo涉及对您的 shell 环境进行一些修改,否则我建议将其设为可执行脚本文件而不是函数,例如将其放入foo命令搜索中某处命名的文件中$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
Run Code Online (Sandbox Code Playgroud)

这具有预期的结果:

> foo
foo
> foo -x
Error: '-x' not a valid option
[1]> foo -h
Shows this help and exits
>
Run Code Online (Sandbox Code Playgroud)

  • 在示例脚本中,例如将“return 0”更改为“exit 0”,然后复制粘贴函数并执行“foo -h”。您运行它的外壳将关闭。根据`exit`手册,它将退出(鱼)外壳。只有在获取文件时调用 exit 才会跳过文件的其余部分而不是退出 shell 本身。 (2认同)