bash
キーワードを使用するか省略して、function
関数を定義できます。違いはありますか?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
関数foo
とbar
の両方の呼び出しが成功し、違いがわかりません。だから、読みやすさを向上させるためだけなのか、それとも私が見逃しているものがあるのか...
ところでdash
(/bin/sh
はdebian/ubuntuのdash
にシンボリックリンクされています)function
キーワードを使用すると失敗します。
2つ目のバージョンの方が移植性が高いという事実を除けば、AFAIKに違いはありません。
function
キーワードは ksh で導入されました。従来の Bourne Shell にはfoo ()
構文しかありませんでした [〜#〜] posix [〜#〜] はfoo ()
のみを標準化します構文。
ATT ksh(pdkshではない)では、function
で定義された関数とBourne/POSIX構文で定義された関数の間にいくつかの違いがあります。 function
で定義された関数では、typeset
キーワードはローカル変数を宣言します。関数が終了すると、変数の値は関数に入る前の値にリセットされます。従来の構文では、typeset
を使用するかどうかにかかわらず、変数にはグローバルスコープがあります。
$ ksh -c 'a=global; f () { typeset a=local; }; f; echo $a'
local
$ ksh -c 'a=global; function f { typeset a=local; }; f; echo $a'
global
Kshのもう1つの違いは、function
キーワードで定義された関数が独自のトラップコンテキストを持つことです。関数の外部で定義されたトラップは、関数の実行中は無視され、関数内の致命的なエラーは、関数全体からではなく関数からのみ終了します。また、$0
はfunction
で定義された関数の関数名ですが、()
で定義された関数のスクリプト名です。
PdkshはATT kshをエミュレートしません。 pdkshでは、typeset
は関数に関係なくローカルスコープの変数を作成し、ローカルトラップはありません(function
を使用すると多少の違いが生じます。詳細はmanページを参照してください)。
Bashとzshは、kshとの互換性のためにfunction
キーワードを導入しました。ただし、これらのシェルでは、function foo { … }
とfoo () { … }
は厳密に同一であり、bashおよびzsh拡張function foo () { … }
も同様です。 typeset
キーワードは常にローカル変数を宣言し(もちろん-g
を除く)、トラップはローカルではありません(local_traps
オプションを設定することにより、zshでローカルトラップを取得できます)。
_foo() any-command
_
bash
、 yash
、および最近のバージョンのposh
(複合コマンドのみをサポート)を除く、BourneのようなシェルでサポートされるBourne構文です。 (ただし、Bourne Shellおよびksh
のAT&T実装は、_any-command
_が複合コマンドでない限り、foo() any-command > redirections
をサポートしていません)。
_foo() any-compound-command
_
(複合コマンドの例:_{ cmd; }
_、_for i do echo "$i"; done
_、_(cmd)
_...最も一般的に使用されるのは_{ ...; }
_)
bourneのようなシェルでサポートされているPOSIX構文であり、一般的に使用したいものです。
_function foo { ...; }
_
bourne構文よりも古いKornシェル構文です。 Korn ShellのAT&T実装用に特別に記述し、そこで受けられる特定の扱いが必要な場合にのみ、これを使用してください。その構文はPOSIXではありませんが、bash
、yash
、zsh
でサポートされています。これらのシェル(およびpdksh
ベースKornシェルのバリアント)は、標準の構文との違いはありません。
_function foo () { ...; }
_
noShellおよび 使用しないでください の構文です。それは偶然に偶然にbash
、yash
、zsh
およびKornシェルのpdksh
ベースのバリアントによってのみサポートされます。ちなみに、これはawk
関数の構文でもあります。
難解なリストを続けていくと、
_function foo() other-compound-command
_
(function foo() (subshell)
またはfunction foo() for i do; ... done
のような)はさらに悪いです。 bash
、yash
およびzsh
ではサポートされていますが、pdksh
ベースのバリアントであってもkshではサポートされていません。
その間:
_function foo() simple command
_
はzsh
でのみサポートされています。
意味的には、これら2つの形式はBashでは同等です。
Manページから:
シェル関数は次のように宣言されています。
name () compound-command [redirection] function name [()] compound-command [redirection]
これは、
name
という名前の関数を定義します。予約語functionはオプションです。 function予約語が指定されている場合、括弧はオプションです。
編集:私はこの質問がposix
とタグ付けされていることに気づきました。 POSIX sh
では、function
キーワードは使用されません(予約されています)。
他のいくつかは今までに正しく答えましたが、ここに私の簡潔な概要があります:
2番目のバージョンは移植可能であり、多くの標準(特にPOSIX)シェルで動作する可能性があります。
最初のバージョンはbashでのみ機能しますが、関数名に続く括弧は省略できます。
それ以外の場合、bashが解釈した後、それらは同一のエンティティを表します。