ソースbashスクリプトで変数をローカルにする最善の方法は何ですか?

ソースbashスクリプトで変数をローカルにする最善の方法は何ですか?

私のコンピュータでいくつかの長期実行タスクの進捗レポートを生成するbashスクリプトがあります。デフォルトでは、この親スクリプトはサブスクリプトのリストを繰り返します(呼び出しを含むsource)。サブスクリプトは、親スクリプトで使用するいくつかの特定の変数を設定する必要があります。

今日、私は最初の添え字に設定された変数が誤って2番目の添え字で使用され、誤った出力が発生するバグを見つけました。この種のエラーが発生しないようにするための確実な方法はありますか?

デフォルトでは、私がsourceサブスクリプトであるときに、いくつかの特定の変数を親スクリプトに戻したいと思います。私の親スクリプトは、それぞれの新しいサブスクリプトの前にこれらの特定の変数をリセットするので、source問題はありません。ただし、一部のサブスクリプトには、親スクリプトに再度保持してはならないローカルで使用される追加のランダム変数があります。

明らかに、下付き文字の末尾でこれらのそれぞれを手動で設定解除することができますが、これらのいずれかを忘れてしまうとエラーが発生しやすいようです。スクリプトをインポートして特定の変数だけが呼び出されたスクリプトに保持するより適切な方法はありますかsource

編集:わかりやすくするために、親スクリプトの単純化されたバージョンは次のとおりです。

echo "<html><body><h1>My jobs</h1>"

FILES=~/confs/*.sh
for f in $FILES; do
  # reset variables
  name="Unnamed job"
  secsSinceActive="Unknown"
  statusText="Unknown"

  # run the script that checks on the job
  source "$f"

  # print bit of report
  echo "<h3>$name</h3>"
  echo "<p>Last active: $secsSinceActive seconds ago</p>"
  echo "<p>Status: $statusText</p>"

echo "</body></html>"

下付き文字の1つは次のとおりです。

name="My awesome job"

nowTime=`expr $(date +%s) `
lastActiveTime=`expr $(date +%s -r ~/blah.log)`
secsSinceActive=`expr $nowTime - $lastActiveTime`

currentRaw=$(cat ~/blah.log | grep "Progress" | tail -n 1)
if [ -z "$currentRaw" ]; then
  statusText="Not running"
else
  statusText="In progress"
fi

$name、$secsSinceActive、および $statusText 変数は親スクリプトに再度保持する必要がありますが、他のすべての変数はサブスクリプトが終了すると消えなければなりません。

ベストアンサー1

関数にインポートするスクリプト全体をラップし、関数でのみ使用したい宣言の前にlocalを追加し、スクリプトの最後に関数を呼び出します。

func () {
    local name="My awesome job"

    nowTime=`expr $(date +%s) `
    lastActiveTime=`expr $(date +%s -r ~/blah.log)`
    local secsSinceActive=`expr $nowTime - $lastActiveTime`

    currentRaw=$(cat ~/blah.log | grep "Progress" | tail -n 1)
    if [ -z "$currentRaw" ]; then
      local statusText="Not running"
    else
      local statusText="In progress"
    fi
}
func

おすすめ記事