Bash

在原始碼的 bash 腳本中使變數本地化的最佳方法?

  • June 8, 2018

我有一個 bash 腳本,可以生成有關機器上一些長期執行的作業的進度報告。基本上,這個父腳本循環遍歷一個子腳本列表(用 呼叫它們source)。子腳本應該設置幾個特定的變數,然後父腳本將使用這些變數。

今天發現一個bug,第一個子腳本設置的變數不小心被第二個子腳本使用了,導致輸出不正確。有沒有一種干淨的方法來防止這些類型的錯誤發生?

基本上,當我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>"

以下是其中一個子腳本的樣子:

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 需要持久化回父腳本,但是當子腳本終止時,所有其他變數都應該消失。

將您要獲取的整個腳本包裝到一個函式中,在您只想在函式中使用的聲明之前添加 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

引用自:https://unix.stackexchange.com/questions/219314