標籤:
我用過bash shell,而且時間不短了。但我從來沒學過shell,至少沒有像C++這麼認真去學。平時寫些基本的指令碼沒問題,不懂也可以google、百度。可在2014最後一天,掉坑裡了。
其實指令碼也很簡單,代碼基本如下:
#!/bin/bashdeclare -A FILES #關聯陣列 bash version >= 4.0cat EX_FILES | while read linedo key=`echo $line | awk ‘{print $1}‘` value=`echo $line | awk ‘{print $2}‘` FILES[$key]=$valuedoneecho ${FILES[@]}
其實也就是從檔案每次讀出一行,再從一行中按列分解出key、value,然後再賦值到map裡去。可以,輸出的map居然為空白。於是,開始了幾個鐘頭的折騰。
一開始以為是關聯陣列的原因,因為是第一次用關聯陣列。可是google、百度,man bash,都是這麼用的。在FILES[$key]=$value這裡列印也是正確的,到while之外FILES卻是空的。然後懷疑是因為key是字串的原因,於是另起一個指令碼測試,key為字串完全沒問題。想想這種情況應該是FILES成了局部變數(按C++的方式,這麼想的),可我聲明FILES時沒用local啊。難道是while read的原因?於是搜尋了一下"while read 局部變數",搜尋到了大量的sub shell相關的問題,也正是我的問題。
在 cat EX_FILES | while ...done 這代碼中,cat EX_FILES是在當前shell中運行,while ...done是在子shell中運行,所以當前shell的數組沒有被賦值。解決的方法改一下就好:
#!/bin/bashdeclare -A FILESwhile read linedo key=`echo $line | awk ‘{print $1}‘` value=`echo $line | awk ‘{print $2}‘` FILES[$key]=$valuedone < EX_FILESecho ${FILES[@]}
這樣要注意EX_FILES可能因為分行符號的原因讀取不了最後一行
學藝不精,又被shell的管道給坑了