質問

私が知る限り、バッシュ関数にローカル変数を作成する方法は2つあります。サブシェルを作成するか、すべての変数をローカルとして宣言します。

例えば:

# using local
function foo
{
  local count
  for count in $(seq 10)
  do
    echo $count
  done
}

また

# using subshell
function foo
{
  (
    for count in $(seq 10)
    do
      echo $count
    done
  )
}

サブシェルを使用するバージョンは、すべての変数をローカル(言うまでもなく(環境)変数を宣言することを気にする必要がないため、書くのが簡単です。 getopts)。しかし、サブシェルを作成するには頭上があると想像できました。

では、より良いアプローチは何ですか?長所/短所は何ですか?

役に立ちましたか?

解決

サブシェルを作成するには、aが含まれます fork(), 、そのため、ローカル変数と比較して間違いなく頭上にあります。サブシェルは安いですが、必要なときにコストを心配する必要はありませんが、無料ではありません。

スクリプトが頻繁に使用され、パフォーマンスが実際に重要である場合(そのため、何百人ものユーザーが1日に何度もそれを実行している場合があります)、サブシェルのパフォーマンスコストについて心配するかもしれません。 OTOH、月に一度実行し、スクリプト全体が10秒以内に実行されると、おそらくそうしないでしょう。

ただし、明確さの観点からは、変数を明示して宣言する方がはるかに優れています。誰かがやって来て、「このサブシェルは明らかに必要ない」と言っているため、スクリプトが壊れるリスクを軽減します(そして、それは本当にそうではありません」 T;私はあなたの関数からサブシェルを削除したいと思います)。

Perlスクリプトの進化を見てください。彼らは、変数がオンデマンドで存在するようになった自由に始まりました。彼らは徐々により厳格になり、通常のスタイルはすべての変数を事前にすることです。ある程度、シェルは同様の道をたどっていますが、Perlほど厳密ではありません。 AWKは興味深いケーススタディでもあります。その関数は、関数の引数でない限り、グローバル変数を使用します。これは、3つのアクティブな引数(たとえば)と局所変数を効果的に定義する5つの非アクティブな引数で書かれている関数につながります。 「機能する」にもかかわらず、わずかに偏心しています。

他のヒント

これで、すべての関数が常にすべての変数をローカルとして宣言することを確認することは非常に困難です。

これは非常にエラーが発生しやすいと思いますが、常にサブシェルファンクションを使用することを好むと思います。

f() (
 echo "we are a subshell"
)

ローカル変数を宣言する必要はありませんが、グローバル変数を変更する方法もありません。私の意見ではそれは良いことです!

追加の結果の1つは、そのような関数の返品 / exitコードを常に確認し、それに応じて行動する必要があることです!これは、サブシェル関数内からスクリプトを終了できないためです!

f() (
   echo "Trying to exit"
   exit 1
)

f
echo "Did not exit"

これはスクリプトを終了しません。このようにする必要があります:

f() (
   echo "Trying to exit"
   exit 1
)

f || exit $?
echo "Did not exit"

これは終了します

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top