2015-06-03 99 views
2

問題,如何增加另一個bash腳本中的全局變量

我想有一個bash腳本,將可以從其他的bash腳本遞增一個全局變量。

例子: 我有類似下面的腳本:

#! /bin/bash 
export Counter=0 
    for SCRIPT in /Users/<user>/Desktop/*sh 
    do 
     $SCRIPT 
    done 
echo $Counter 

該腳本會調用所有的文件夾中的其他的bash腳本和這些腳本將有類似如下:

if [ "$Output" = "$Check" ] 
    then 
     echo "OK" 
     ((Counter++)) 

我希望它增加$ Counter變量,如果它確實等於「OK」,然後將該值返回到初始批處理腳本,以便我可以保留該計數器編號並在最後有一個總計。

有關如何去做這件事的任何想法?

+1

您需要使用文件系統,因爲子進程無法更改其父母的環境。 –

+0

@CharlesDuffy請詳細說明一下,我該如何去做這個 – Technic1an

+0

如果你不能處理主循環中的增量(這是一個靜態增加每個腳本),那麼你可以輸出計數到主腳本可以讀取的文件每個循環或使用一個文件,每個腳本在開始時讀取並在末尾寫入/ etc。 –

回答

5

環境變量只沿一個方向傳播 - 從父母到孩子。因此,子進程無法更改其父級中設置的環境變量的值。

你可以做的是使用文件系統:

export counter_file=$(mktemp "$HOME/.counter.XXXXXX") 
for script in ~user/Desktop/*sh; do "$script"; done 

...,在各個腳本:

counter_curr=$(< "$counter_file") 
((++counter_curr)) 
printf '%s\n' "$counter_curr" >"$counter_file" 

這不是當前併發安全的,但你的父母腳本因爲目前寫的永遠不會多次給一個孩子打電話。


一個更簡單的方法,假設您正在跟蹤的價值仍然相對較小,是使用文件的大小作爲計數器的值的代理。要做到這一點,增加計數器是如此簡單:

printf '\n' >>"$counter_file" 

...並檢查其在O(1)時間價值 - 而無需打開該文件並閱讀其內容 - 就是這麼簡單作爲檢查文件的大小;與GNU stat

counter=$(stat --format=%z "$counter_file") 

注意,鎖定可能如果使用文件系統,比如NFS不正確地實現O_APPEND需要爲這是併發安全;請參閱Norman Gray's answer(這是它的靈感來源)。

+0

當涉及到bash時,我不是一個智者,所以請耐心等待....當你說$ counter_file是在「mktemp」部分創建的文件嗎? – Technic1an

+0

正確。 'mktemp'創建一個唯一的文件名,所以同時運行的這個腳本的幾個副本都有自己的計數器。 –

+0

真棒,工作感謝查爾斯! – Technic1an

2

你可以source其他腳本,這意味着他們不會在子進程中運行,但在調用腳本「內聯」是這樣的:

#! /bin/bash 
export counter=0 
    for script in /Users/<user>/Desktop/*sh 
    do 
     source "$script" 
    done 
echo $counter 

但在我要作的評論中指出如果你自己控制被調用的腳本,d只建議使用這種方法。如果他們例如exit或變量相互衝突,可能會發生不好的事情。

+1

這種方法有效,但是存在很大的風險 - 意味着父進程中的exit或exec會阻止將來的腳本運行。 –

+0

更新了答案,好嗎? –

+0

相當;我的upvote被修改了。 –

1

如上所述,您不能這樣做,因爲沒有任何內容對應於shell腳本的'全局變量'。

正如評論所示,您必須使用文件系統在腳本之間進行通信。做你的描述是簡單地已分別配合腳本添加一行到文件什麼的

一個簡單的/粗暴的方式,和「全球計數」是這個文件的大小:

#! /bin/sh - 
echo ping >>/tmp/scriptcountfile 

然後wc -l /tmp/scriptcountfile是發生的次數。當然,這裏存在潛在的競爭條件,所以像下面將排序這些訪問:

#! /bin/sh - 
(
flock -n 9 
echo 'do stuff...' 
echo ping >>/tmp/stampfile 
) 9>/tmp/lockfile 

(該flock命令在Linux上使用,但不可移植)。

當然,您可以通過腳本通過管道和套接字發送內容來開始做更有趣的事情,但這種做法有點過分了。

+0

實際上''echo >> countfile'不應該沒有鎖定,除非你的文件系統是NFS或其他沒有正確實現'O_APPEND'的東西。與'>>'一樣,在'O_APPEND'模式下打開意味着寫操作總是直接進行到底部,無論其他任何操作是否進行併發修改。您需要保持足夠小的寫入次數,以使它們不會被拆分成兩個系統調用,而是將它作爲一個單字節的換行符追加來解決這個問題。 –

+0

介意我是否偷了你的方法(追加/追蹤大小)? –

+0

@CharlesDuffy關於'O_APPEND'的好處(謝謝:我以前從未真正內化過'open(2)'行爲)。你說得對,這可能是矯枉過正的,但如果OP做的比重量級更重要的話,它可能會很有用。並重新(ii),感覺自由... –

相關問題