Bashまたはシェルスクリプトで関数宣言を転送しますか?


95

たとえば、bashC / C ++でよく知られている、前方宣言のような、またはそれに似た(回避策)のようなものはありますか?

または、たとえば、常に1つのパス(行ごと)で実行されるため、そのようなものがありますか?

前方宣言がない場合、スクリプトを読みやすくするにはどうすればよいですか。それはかなり長く、最初はこれらの関数定義がグローバル変数と混合されているため、スクリプトが見苦しく、読みにくく/理解しにくくなっています)?私はそのような場合のいくつかのよく知られている/ベストプラクティスを学ぶことを求めています。


例えば:

# something like forward declaration
function func

# execution of the function
func

# definition of func
function func
{
    echo 123
}

回答:


190

すばらしい質問です。ほとんどのスクリプトで次のようなパターンを使用しています。

#!/bin/bash

main() {
    foo
    bar
    baz
}

foo() {
}

bar() {
}

baz() {
}

main "$@"

コードは上から下まで読むことができますが、実際には最後の行まで実行を開始しません。"$@"main()に渡すことにより、通常と同じようにコマンドライン引数$1$2などにアクセスできます。


3
こんにちは、あなたの例ではfoo / bar / baz間で共有する必要があるデータをどのように構成しますか?通常は、スクリプトの先頭に配置します。これは関数を使用する場合にも当てはまりますか?または、グローバルデータをメインに配置して、それをfoo / bar / bazに引数として渡す方がよいでしょうか。ベストプラクティスは何ですか?
bodacydo

4
私は議論を好みます。それを除いて、main直後に関数内または関数内にグローバル変数を設定しますmain(例:setupまたはparseArguments)。上記でグローバル変数を設定することは避けますmain-コードは外に出るべきではありませんmain
John Kugelman、2015

これはif _ _ name _ _ == "_ _ main _ _": main()pythonでの動作に多少似ているようです
Sergiy Kolodyazhnyy

これは、Batsなどのツールを使用してスクリプトをテストする場合にも便利です。すべてを機能に分解すると、個々のコンポーネントのテストがはるかに簡単になります。ブログ投稿
dragon788

30

私のbashスクリプトが大きくなりすぎると、インクルードメカニズムを使用します。

ファイルallMyFunctions

foo() {
}

bar() {
}

baz() {
}

ファイルmain

#!/bin/bash

. allMyfunctions

foo
bar
baz

27
個人的に、シェルスクリプトが1つのファイルを超えて成長し始めると、私は別の言語に切り替える傾向があります;-)
Joachim Sauer

使うほうがいいのではsource allMyfunctions
pydoge 2018

4
@pydoge:sourcePOSIXに準拠していません。bashsourceエイリアスとして定義し.ます。これらは機能的に同等です。
mouviciel 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.