web-dev-qa-db-ja.com

以下で宣言された関数を呼び出す

以下で宣言されている関数をbashで呼び出すことは可能ですか?

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

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

NO_FUNCTION()
{
  .....
  .....
}
15
msp9011

他の人が言ったように、あなたはそれを行うことができません。

ただし、メインプログラムがファイルの先頭にあり、他の関数が以下で定義されるようにコードを1つのファイルに配置する場合は、別のmain関数を使用することで実行できます。

例えば。

#!/bin/sh

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

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

main "$@"; exit

ファイルの最後でmainを呼び出すと、すべての関数が既に定義されています。明示的に渡す"$@"からmainは、スクリプトのコマンドライン引数を関数で表示するために必要です。

Mainの呼び出しと同じ行の明示的なexitは必須ではありませんが、スクリプトファイルが変更された場合に実行中のスクリプトが混乱しないようにするために使用できます。これがないと、シェルはmainが戻った後もスクリプトファイルからコマンドの読み取りを続けようとします。 ( (実行する前にシェルスクリプト全体を読む方法は? を参照)

37
ilkkachu

いいえ、関数は、それらを呼び出すときにシェル環境に存在している必要があります。

Googleの "Shell Style Guide" はこれを修正しています:

mainという関数は、少なくとも1つの他の関数を含めるのに十分な長さのスクリプトに必要です。

スクリプトの最後で、すべての関数の後に、関数内にない唯一のステートメントとして、

main "$@"

これにより、スクリプトに指定されたパラメーターを使用してmain関数が呼び出されます。 main関数は、スクリプトの上部に配置することができます(スタイルガイドでは、これを下部に配置するように指示されていますが、多くのことを説明しています)。

シェルがmain呼び出しに到達すると、スクリプト内のすべての関数が解析されているため、main関数内から呼び出すことができます。

14
Kusalananda

いいえ、関数は使用する前に宣言する必要があります。シェルスクリプトは1行ずつ読み込まれ、1行ずつ実行されます。そのため、宣言が実行されるまで関数は存在しません。

9
Stephen Kitt

シェルには、declaring関数という概念はありません。したがって、前方宣言はできません。

その結果、シェルを呼び出す前に、シェルで関数の実装を読み取る必要があります。

4
schily