下面声明的调用函数

Siv*_*iva 25 linux shell-script function

是否可以调用下面在 bash 中声明的函数?

例子

if [ "$input" = "yes" ]; then
    YES_FUNCTION
elif [ "$input" = "no" ]; then
    NO_FUNCTION
else
    exit 0;
fi

YES_FUNCTION()
{
  .....
  .....
}

NO_FUNCTION()
{
  .....
  .....
}
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 52

就像其他人说的,你不能那样做。

但是如果你想把代码整理成一个文件,让主​​程序在文件的顶部,其他的函数定义在下面,你可以通过单独的main函数来实现。

例如

#!/bin/sh

main() {
    if [ "$1" = yes ]; then
        do_task_this
    else
        do_task_that
    fi
}

do_task_this() {
    ...
} 
do_task_that() {
    ...
} 

main "$@"; exit
Run Code Online (Sandbox Code Playgroud)

当我们main在文件末尾调用时,所有的函数都已经定义好了。需要显式传递"$@"tomain以使脚本的命令行参数在函数中可见。

exit在调用 main 的同一行中的显式不是强制性的,但可用于防止脚本文件被修改时正在运行的脚本变得混乱。如果没有它,shell 将尝试在main返回后继续从脚本文件中读取命令。(请参阅如何在执行之前读取整个 shell 脚本?)

  • 有`main "$@"; exit`(与 `main` 位于同一行的 `exit`)也可用作防止文件在解释时被修改的保护措施。 (11认同)
  • 对于 Bash 脚本,我经常使用 `[[ ${BASH_SOURCE[0]} = "$0" ]] && Main "$@"` 来调用 main 函数,这样我就可以在另一个脚本中获取它,而无需执行 `Main`。然后我可以重用这些函数或编写测试来检查它们。 (8认同)
  • @JoL,读取的内容不会再次读取,shell 需要在开始运行之前读取并解析循环的整个文本,但是在循环返回后,它将继续从文件的其余部分读取当前位置(如果文件已被修改,它将把事情搞砸)。如果一切都在函数中,shell 需要在开始做任何事情之前读取所有内容(除了定义这些函数),如果我们将 `exit` 与 `main` 放在同一行,我们确保 shell 不会再次读取任何内容来自`main`返回后的文件。 (2认同)

Kus*_*nda 15

不,这些函数在调用它们时必须存在于 shell 环境中。

Google 的“Shell Style Guide”对此进行了修复:

main足够长的脚本需要一个被调用的函数,以包含至少一个其他函数。

在脚本的最后,在所有函数之后,作为唯一不在函数中的语句,您将有

main "$@"
Run Code Online (Sandbox Code Playgroud)

这将main使用给定脚本的任何参数调用该函数。该main函数可以位于脚本的顶部(样式指南说把它放在底部,但话又说回来,它说了很多事情)。

当 shell 开始main调用时,脚本中的所有函数都已被解析,因此可以从main函数内部调用。


Ste*_*itt 9

不,函数必须在使用之前声明。Shell 脚本被逐行读取并逐行执行;所以一个函数在它的声明被执行之前不存在。

  • 您可以将您的函数声明放在另一个文件中并获取它(`.yourfile`)。 (3认同)