スクリプトファイルの最後にヘルパー関数を入れる方法はありますか?

スクリプトファイルの最後にヘルパー関数を入れる方法はありますか?

私はこれがうまくいくと思いました:

source <(sed '1,/# HELPER FUNCTIONS #/d' "$0")
fun abc

# HELPER FUNCTIONS #
fun() {
  echo"$@"
}

しかし、今考えてみると、スクリプトが完了したら、ヘルパー関数を現在のシェルにインポートします。

スクリプトの最後にヘルパー関数を入れる方法はありますか?

答え1

sourceあなたのアプローチは実際には機能しますが、ヘルパー関数を宣言するステートメントは実行前と実行後に1回、2回実行されますfun abc。それで、exit区切り線の前に簡単な文章を挿入します。

#!/bin/bash

source <(sed '1,/^# HELPER FUNCTIONS #$/d' "$0")
fun ABC

exit
# HELPER FUNCTIONS #

fun () {
  echo "$@"
}

また、正規表現を少なくとも行の先頭に固定する必要があります。それ以外の場合は、commandが含まれている行と一致し、最終的にスクリプトのsource最初の半分が回避sedによって実行されますsource

個人的に、私はこれがコードを読みにくくしていると思います。また、区切り記号の後に何かが変更されます。たとえば、BASH_SOURCE配列は最初の要素として追加のファイル名を持ち、BASH_LINENOスクリプトの初期部分サイズに基づいてオフセットされ、スクリプトの下部にあるエラーメッセージに報告された行番号(およびスクリプト名)は難しくなります。続く。


$0合理的な値を持つスクリプトや動的に変更するスクリプトを呼び出すことなくこれを実行するもう1つの方法は、sedスクリプトの本文を独自の関数(おそらく呼び出される)に入れてmainから、スクリプトの最後にこれを呼び出す習慣を持ち上げることです。機能:

#!/bin/sh

main () {
    fun ABC
}

fun () {
    echo "$@"
}

# Call "main" with the arguments given to the script
# (even if the function may not use them).
main "$@"

これは、シェルが最後までスクリプトを読み取り、すべての関数がインスタンス化され、その関数がmainコードの場所に関係なく、操作を実行するために必要なすべての関数を呼び出すことができることを意味します。

また、シェルスクリプトのGoogleスタイルガイドもご覧ください。これを提案するmain、関数のコードを最後に入れるようになっていますが必ずしも必要ではありません。実際に言及する価値があるかもしれません。最初簡単に見つけることができます。

関連:

関連情報