本篇文章介紹一個(gè)解析、以及增刪改查鍵值對(duì)格式配置文件的 bash shell 腳本。
該 shell 腳本處理的基本配置格式信息是:key|value。
在腳本中,把 key 稱為 “鍵名”。把 value 稱為 “鍵值”。
把整個(gè) key|value 稱為 “鍵值對(duì)”。
把中間的 | 稱為 “分隔符”。
默認(rèn)的分隔符是 |。腳本里面提供了設(shè)置函數(shù)可以修改分隔符的值,以便自定義。
基于這個(gè)配置格式,可以配置下面的一些信息。
配置目錄路徑簡(jiǎn)寫
配置一個(gè)目錄路徑簡(jiǎn)寫,通過(guò)一個(gè)、或幾個(gè)字符,就可以快速 cd 到很深的目錄底下。
例如,在配置文件中有下面的信息:
am|frameworks/base/services/core/JAVA/com/Android/server/am/
w|frameworks/base/wifi/java/android/net/wifi/
假設(shè)有一個(gè) quickcd.sh 腳本可以解析這個(gè)配置信息。
在執(zhí)行 quickcd.sh w 命令時(shí),該腳本會(huì)基于 w 這個(gè)鍵名,獲取到 frameworks/base/wifi/java/android/net/wifi/ 這個(gè)鍵值。
然后腳本里面執(zhí)行 cd frameworks/base/wifi/java/android/net/wifi/ 命令,進(jìn)入到對(duì)應(yīng)的目錄下。
這樣就不需要輸入多個(gè)字符,非常方便。
后面的文章會(huì)介紹在不同目錄之間快速來(lái)回 cd 的 quickcd.sh 腳本。
同時(shí),所解析的配置信息保存在配置文件里面。
如果要新增、刪除配置項(xiàng),修改配置文件自身即可,不需要改動(dòng)腳本代碼。
這樣可以實(shí)現(xiàn)程序數(shù)據(jù)和程序代碼的分離,方便復(fù)用。
配置命令簡(jiǎn)寫
配置一個(gè)命令簡(jiǎn)寫,通過(guò)一個(gè)、或幾個(gè)字符,就可以執(zhí)行相應(yīng)的命令。
例如,在配置文件中有如下的信息:
l|adb logcat -b all -v threadtime
png|adb shell "screencap /sdcard/screen.png"
這里配置了 Android 系統(tǒng)的 adb 命令。
類似的,假設(shè)有一個(gè) quickadb.sh 腳本可以解析這個(gè)配置信息。
執(zhí)行 quickadb.sh l 命令,該腳本實(shí)際會(huì)執(zhí)行 adb logcat -b all -v threadtime 命令。
這樣可以減少輸入,快速執(zhí)行內(nèi)容比較長(zhǎng)的命令。
使用配置文件保存命令簡(jiǎn)寫,可以動(dòng)態(tài)添加、刪除命令,跟腳本代碼獨(dú)立開(kāi)來(lái)。
后面的文章會(huì)介紹一個(gè)通過(guò)命令簡(jiǎn)寫執(zhí)行對(duì)應(yīng)命令的 tinyshell.sh 腳本。
使用場(chǎng)景總結(jié)
總的來(lái)說(shuō),這里介紹的配置文件是基于鍵值對(duì)的形式。
常見(jiàn)的使用場(chǎng)景是,提供比較簡(jiǎn)單的鍵名來(lái)獲取比較復(fù)雜的鍵值,然后使用鍵值來(lái)進(jìn)行一些操作。
但是在實(shí)際輸入的時(shí)候,只需要輸入鍵名即可,可以簡(jiǎn)化輸入,方便使用。
當(dāng)然,實(shí)際使用并不局限于這些場(chǎng)景。
如果有其他基于鍵值對(duì)的需求,可以在對(duì)應(yīng)的場(chǎng)景上使用。
腳本使用方法
這個(gè)解析配置文件的 shell 腳本是一個(gè)獨(dú)立的腳本,可以在其他腳本里面通過(guò) source 命令進(jìn)行調(diào)用。
假設(shè)腳本文件名為 parsecfg.sh,調(diào)用該腳本的順序步驟說(shuō)明如下:
- source parsecfg.sh:在調(diào)用者的腳本中引入 parsecfg.sh 腳本的代碼,以便后續(xù)調(diào)用 parsecfg.sh 腳本里面的函數(shù)。這里需要通過(guò) source 命令來(lái)調(diào)用,才能共享 parsecfg.sh 腳本里面的函數(shù)、全局變量值。
- (可選的)set_info_ifs separatorset_info_ifs:這是 parsecfg.sh 腳本里面的函數(shù),用于設(shè)置分隔符。所給的第一個(gè)參數(shù)指定新的分隔符。默認(rèn)分隔符是 |。如果需要解析的配置文件用的是其他分隔符,就需要先設(shè)置分隔符,再解析配置文件。如果使用默認(rèn)的分隔符,可以跳過(guò)這個(gè)步驟。
- open_config_file filenameopen_config_file:這是 parsecfg.sh 腳本里面的函數(shù),用于解析配置文件。所給的第一個(gè)參數(shù)指定配置文件名。
- (可選的)handle_config_option -l|-v|-i|-e|-a|-dhandle_config_option:這是 parsecfg.sh 腳本里面的函數(shù),用于處理選項(xiàng)參數(shù)。‘-l’ 選項(xiàng)打印配置文件本身的內(nèi)容。‘-v’ 選項(xiàng)以鍵值對(duì)的形式打印所有配置項(xiàng)的值。‘-i’ 選項(xiàng)后面要跟著一個(gè)參數(shù),查詢?cè)搮?shù)值在配置文件中的具體內(nèi)容。‘-e’ 選項(xiàng)使用 vim 打開(kāi)配置文件,以便手動(dòng)編輯。‘-a’ 選項(xiàng)后面跟著一個(gè)參數(shù),把指定的鍵值對(duì)添加到配置文件末尾。‘-d’ 選項(xiàng)后面跟著一個(gè)參數(shù),從配置文件中刪除該參數(shù)所在的行。如果沒(méi)有需要處理的選項(xiàng),可以跳過(guò)這個(gè)步驟。
- 解析配置文件后,就可以調(diào)用 parsecfg.sh 腳本提供的功能函數(shù)來(lái)進(jìn)行一些操作。get_key_of_entry 函數(shù)從 “key|value” 形式的鍵值對(duì)中獲取到 key 這個(gè)鍵名。get_value_of_entry 函數(shù)從 “key|value” 形式的鍵值對(duì)中獲取到 value” 這個(gè)鍵值。get_value_by_key 函數(shù)在配置文件中基于所給鍵名獲取到對(duì)應(yīng)的鍵值。search_value_from_file 函數(shù)在配置文件中查找所給的內(nèi)容,打印出匹配的行。delete_key_value 函數(shù)從配置文件中刪除所給鍵名對(duì)應(yīng)的行。Append_key_value 函數(shù)把所給的鍵值對(duì)添加到配置文件的末尾。
parsecfg.sh 腳本代碼
列出 parsecfg.sh 腳本的具體代碼如下所示。
在這個(gè)代碼中,幾乎每一行代碼都提供了詳細(xì)的注釋,方便閱讀。
這篇文章的后面也會(huì)提供一個(gè)參考的調(diào)用例子,有助理解。
#!/bin/bash
# 這個(gè)腳本提供函數(shù)接口來(lái)解析、處理鍵值對(duì)格式的配置文件.
# 默認(rèn)的配置格式為: key|value. 該腳本提供如下功能:
# 1.根據(jù)所提供的 key 獲取到對(duì)應(yīng)的 value.
# 2.查看配置文件的內(nèi)容.
# 3.使用 vim 打開(kāi)配置文件,以供編輯.
# 4.提供函數(shù)來(lái)插入一個(gè)鍵值對(duì)到配置文件中.
# 5.提供函數(shù)從配置文件中刪除所給 key 對(duì)應(yīng)的鍵值對(duì).
# 上面的 | 是鍵名和鍵值之間的分隔符.腳本提供set_info_ifs()函數(shù)來(lái)設(shè)置新的值.
# 下面變量保存?zhèn)魅氲呐渲梦募?
PARSECFG_filepath=""
# 定義配置文件中鍵名和鍵值的分隔符. 默認(rèn)分隔符是 '|'.
# 可以調(diào)用 set_info_ifs() 函數(shù)來(lái)修改分隔符的值,指定新的分隔符.
info_ifs="|"
######## 下面函數(shù)是當(dāng)前腳本實(shí)現(xiàn)的功能函數(shù) ########
# 從傳入的項(xiàng)中提取出鍵名,并把鍵名寫到標(biāo)準(zhǔn)輸出,以供調(diào)用者讀取.
# 下面echo的內(nèi)容要用雙引號(hào)括起來(lái).雙引號(hào)可以避免進(jìn)行路徑名擴(kuò)展等.
# 當(dāng)所echo的內(nèi)容帶有 '*' 時(shí),不加雙引號(hào)的話, '*' 可能會(huì)進(jìn)行路徑
# 名擴(kuò)展,導(dǎo)致輸出結(jié)果發(fā)生變化. 后面的幾個(gè)函數(shù)也要參照這個(gè)處理.
get_key_of_entry()
{
local entry="$1"
# ${param%%pattern} 表達(dá)式刪除匹配的后綴,返回前面剩余的部分.
echo "${entry%%${info_ifs}*}"
}
# 從傳入的項(xiàng)中提取出鍵值,并把鍵值寫到標(biāo)準(zhǔn)輸出,以供調(diào)用者讀取.
get_value_of_entry()
{
local entry="$1"
# ${param#pattern} 表達(dá)式刪除匹配的前綴,返回后面剩余的部分.
echo "${entry#*${info_ifs}}"
}
# 該函數(shù)根據(jù)傳入的鍵名從 key_values 關(guān)聯(lián)數(shù)組中獲取對(duì)應(yīng)鍵值.
# 如果匹配,將鍵值寫到標(biāo)準(zhǔn)輸出,調(diào)用者可以讀取該標(biāo)準(zhǔn)輸出來(lái)獲取鍵值.
# 該函數(shù)把查詢到的鍵值寫入到標(biāo)準(zhǔn)輸出的鍵值. 如果沒(méi)有匹配所提供
# 鍵名的鍵值,輸出會(huì)是空. 調(diào)用者需要檢查該函數(shù)的輸出是否為空.
get_value_by_key()
{
# 所給的第一個(gè)參數(shù)是要查詢的鍵名.
local key="$1"
# 使用鍵名從鍵值對(duì)數(shù)組中獲取到鍵值,并輸出該鍵值.
echo "${key_values["${key}"]}"
}
# 根據(jù)傳入的鍵名刪除配置文件中對(duì)應(yīng)該鍵名的行.
delete_entry_by_key()
{
# 所給的第一個(gè)參數(shù)是要?jiǎng)h除的鍵名,會(huì)刪除對(duì)應(yīng)的鍵值對(duì).
local key="$1"
# 這里要在${key}的前面加上^,要求${key}必須在行首.
sed -i "/^${key}|/d" "${PARSECFG_filepath}"
# 將關(guān)聯(lián)數(shù)組中被刪除鍵名對(duì)應(yīng)的鍵值設(shè)成空.
# key_values["${key}"]=""
# 將鍵值設(shè)成空,這個(gè)鍵名還是存在于數(shù)組中.可以用 unset name[subscript]
# 命令移除指定下標(biāo)的數(shù)組元素.移除之后,這個(gè)數(shù)組元素在數(shù)組中已經(jīng)不存在.
# 注意用雙引號(hào)把整個(gè)數(shù)組元素括起來(lái). unset 命令后面的參數(shù)會(huì)進(jìn)行路徑名
# 擴(kuò)展.例如提供key_values[s]參數(shù),如果當(dāng)前目錄下有一個(gè)key_valuess文件,
# 那么key_values[s]會(huì)對(duì)應(yīng) key_valuess,而不是對(duì)應(yīng)數(shù)組下標(biāo)為s的數(shù)組元素.
# 為了避免這個(gè)問(wèn)題,使用雙引號(hào)把整個(gè)數(shù)組元素括起來(lái),不進(jìn)行路徑名擴(kuò)展.
unset "key_values[${key}]"
}
# 根據(jù)傳入的鍵名,刪除它在配置文件中對(duì)應(yīng)的行
delete_key_value()
{
if [ $# -ne 1 ]; then
echo "Usage: $FUNCNAME key_name"
return 1
fi
local key="$1"
# 如果所給的鍵名在配置文件中已經(jīng)存在,get_value_by_key()函數(shù)輸出
# 的內(nèi)容不為空. 判斷該函數(shù)的輸出內(nèi)容,不為空時(shí)才進(jìn)行刪除.
local value=$(get_value_by_key "${key}")
if test -n "${value}"; then
delete_entry_by_key "${key}"
else
echo "出錯(cuò): 找不到路徑簡(jiǎn)寫 '${key}' 對(duì)應(yīng)的行"
fi
}
# 該函數(shù)先從傳入的鍵值對(duì)中解析出鍵名,然后執(zhí)行g(shù)et_value_by_key()
# 函數(shù)來(lái)判斷該鍵名是否已經(jīng)在配置文件中,如果在,就刪除該鍵名對(duì)應(yīng)的行.
# 最終,新傳入的鍵值對(duì)會(huì)被追加到配置文件的末尾.
append_key_value()
{
if [ $# -ne 1 ]; then
echo "Usage: $FUNCNAME key_value"
return 1
fi
# 所給的第一個(gè)參數(shù)是完整的鍵值對(duì).
local full_entry="$1"
# 從傳入的鍵值對(duì)中解析出鍵名
local key_name=$(get_key_of_entry "${full_entry}")
# 從配置文件中獲取該鍵名對(duì)應(yīng)的值.如果能夠獲取到值,表示該鍵名已經(jīng)存在
# 于配置文件中,會(huì)先刪除這個(gè)鍵值對(duì),再追加新傳入的鍵值對(duì)到配置文件末尾.
local match_value=$(get_value_by_key "${key_name}")
if test -n "${match_value}"; then
echo "更新 ${key_name}${info_ifs}${match_value} 為: ${full_entry}"
delete_entry_by_key "${key_name}"
fi
# 追加新的鍵值對(duì)到配置文件末尾
echo "${full_entry}" >> "${PARSECFG_filepath}"
# 將新項(xiàng)的鍵名和鍵值添加到 key_values 數(shù)組中,以便實(shí)時(shí)反應(yīng)這個(gè)修改.
key_values["${key_name}"]="$(get_value_of_entry "${full_entry}")"
}
# 使用 cat 命令將配置文件的內(nèi)容打印到標(biāo)準(zhǔn)輸出上.
show_config_file()
{
echo "所傳入配置文件的內(nèi)容為:"
cat "${PARSECFG_filepath}"
}
# 打印從配置文件中解析得到的鍵值對(duì).
show_key_values()
{
local key_name
# ${!array[@]} 對(duì)應(yīng)關(guān)聯(lián)數(shù)組的所有鍵. ${array[@]}對(duì)應(yīng)關(guān)聯(lián)數(shù)組的所有值.
# 下面先獲取關(guān)聯(lián)數(shù)組的鍵,再通過(guò)鍵名來(lái)獲取鍵值,并把鍵名和鍵值都打印出來(lái).
for key_name in "${!key_values[@]}"; do
printf "key='e[32m${key_name}e[0m' t"
printf "value='e[33m${key_values["${key_name}"]}e[0m'n"
done
}
# 使用 vim 打開(kāi)配置文件,以供編輯. 注意: 使用vim編輯文件后,文件所發(fā)生的改動(dòng)不能
# 實(shí)時(shí)在腳本中反應(yīng)出來(lái),需要再次執(zhí)行腳本,重新讀取配置文件才能獲取到所作的修改.
# 為了避免這個(gè)問(wèn)題,在退出編輯后,主動(dòng)調(diào)用open_config_file函數(shù),重新解析配置文件.
edit_config_file()
{
vim "${PARSECFG_filepath}"
# 調(diào)用 open_config_file() 函數(shù)解析配置文件,重新為 key_values 賦值.
open_config_file "${PARSECFG_filepath}"
}
# 在配置文件中查找指定的內(nèi)容,看該內(nèi)容是否在配置文件中.
search_value_from_file()
{
# 如果查找到匹配的內(nèi)容,grep命令會(huì)打印匹配的內(nèi)容輸出,以便查看.
grep "$1" "${PARSECFG_filepath}"
if [ $? -ne 0 ]; then
echo "配置文件中不包含所給的 '$1'"
return 1
fi
}
######## 下面函數(shù)是初始化時(shí)需要調(diào)用的函數(shù) ########
# 該函數(shù)用于設(shè)置配置文件中鍵名和鍵值的分隔符.
# 所給的第一個(gè)參數(shù)會(huì)指定新的分隔符,并覆蓋之前設(shè)置的分隔符.
set_info_ifs()
{
if [ $# -ne 1 ]; then
echo "Usage: $FUNCNAME separator"
return 1
fi
if [ -n "${PARSECFG_filepath}" ]; then
# 如果配置文件名不為空,說(shuō)明之前已經(jīng)解析過(guò)配置文件.
# 那么之前解析文件沒(méi)有使用新的分隔符,報(bào)錯(cuò)返回.需要
# 調(diào)用者修改代碼,先調(diào)用當(dāng)前函數(shù),再調(diào)用open_config_file()
# 函數(shù),以便使用新指定的分隔符來(lái)解析配置文件的內(nèi)容.
echo "出錯(cuò): 設(shè)置分隔符要先調(diào)用 set_info_ifs,再調(diào)用 open_config_file."
return 2
fi
info_ifs="$1"
}
# 讀取配置文件,并將配置文件的內(nèi)容保存到關(guān)聯(lián)數(shù)組中. 每次解析配置文件
# 之前,都要先調(diào)用該函數(shù).后續(xù)直接通過(guò)關(guān)聯(lián)數(shù)組來(lái)獲取對(duì)應(yīng)的值,不再多次
# 打開(kāi)文件. 該函數(shù)接收一個(gè)參數(shù),指定要解析的配置文件路徑名.
open_config_file()
{
if [ $# -ne 1 ]; then
echo "Usage: $FUNCNAME config_filename"
return 1
fi
# 判斷所給的配置文件是否存在,且是否是文本文件.
if [ ! -f "${1}" ]; then
echo "ERROR: the file '${1}' does not exist"
return 2
fi
# 存在配置文件,則把文件路徑名保存到 PARSECFG_filepath 變量.
# 使用 readlink -f 命令獲取文件的絕對(duì)路徑,包括文件名自身.
# 一般來(lái)說(shuō),所給的文件名是相對(duì)路徑.后續(xù) cd 到其他目錄后,用
# 所給的相對(duì)路徑會(huì)找不到這個(gè)文件, -l 選項(xiàng)無(wú)法查看文件內(nèi)容.
PARSECFG_filepath="$(readlink -f $1)"
# 定義一個(gè)關(guān)聯(lián)數(shù)組,保存配置文件中的鍵值對(duì). 要先重置key_values的定義,
# 避免通過(guò) source 命令調(diào)用該腳本時(shí), key_values 所保存的值沒(méi)有被清空,
# 造成混亂. 在函數(shù)內(nèi)使用 declare 聲明變量,默認(rèn)是局部變量,跟 local
# 命令類似. 使用 declare -g 可以在函數(shù)內(nèi)聲明變量為全局變量.
unset key_values
declare -g -A key_values
local key value entryline
# 逐行讀取配置文件,并從每一行中解析出鍵名和鍵值,保存到關(guān)聯(lián)數(shù)組
# key_values中.后續(xù)直接通過(guò)鍵名來(lái)獲取鍵值.如果鍵名不存在,鍵值為空.
while read entryline; do
# 由于配置文件的鍵值中可能帶有空格,下面的${entryline}要用雙引號(hào)
# 括起來(lái),避免帶有空格時(shí),本想傳入一個(gè)參數(shù),卻被分割成了多個(gè)參數(shù).
# 例如${entryline}是service list,在不加引號(hào)時(shí),get_value_of_entry()
# 函數(shù)會(huì)接收到兩個(gè)參數(shù),第一個(gè)參數(shù)是$1,對(duì)應(yīng)service,第二個(gè)參數(shù)是$2,
# 對(duì)應(yīng)list,而get_value_of_entry()函數(shù)只獲取了第一個(gè)參數(shù)的值,這樣就
# 會(huì)處理出錯(cuò).在傳遞變量值給函數(shù)時(shí),變量值一定要用雙引號(hào)括起來(lái).
key=$(get_key_of_entry "${entryline}")
value=$(get_value_of_entry "${entryline}")
# 經(jīng)過(guò)驗(yàn)證,當(dāng) key_values[] 后面跟著等號(hào)'='時(shí),所給的[]不會(huì)進(jìn)行
# 路徑名擴(kuò)展,不需要像上面用 unset 命令移除數(shù)組元素那樣用雙引號(hào)
# 把整個(gè)數(shù)組元素括起來(lái)以避免路徑名擴(kuò)展.
key_values["${key}"]="${value}"
# 下面是預(yù)留的調(diào)試語(yǔ)句.在調(diào)試的時(shí)候,可以打開(kāi)下面的注釋.
# echo "entryline=${entryline}"
# echo "key=${key}"
# echo "value=${value}"
done < "${PARSECFG_filepath}"
# 查看關(guān)聯(lián)數(shù)組 key_values 的值.調(diào)試的時(shí)候,可以打開(kāi)下面的注釋.
# declare -p key_values
}
# 操作配置文件的功能選項(xiàng).建議外部調(diào)用者通過(guò)功能選項(xiàng)來(lái)指定要進(jìn)行的操作.
# 該函數(shù)最多接收兩個(gè)參數(shù):
# 第一個(gè)參數(shù): 提供選項(xiàng)名,該選項(xiàng)名要求以'-'開(kāi)頭,才是合法選項(xiàng).
# 第二個(gè)參數(shù): 提供選項(xiàng)的參數(shù). 部分選項(xiàng)后面需要跟著一個(gè)參數(shù).
# 當(dāng)傳入的選項(xiàng)被handle_config_option()函數(shù)處理時(shí),該函數(shù)返回處理后的狀態(tài)碼.
# 例如,處理成功返回0,失敗返回非0. 當(dāng)傳入的選項(xiàng)不被該函數(shù)處理時(shí),它返回127.
handle_config_option()
{
if [ -z "${PARSECFG_filepath}" ]; then
# 如果配置文件變量值為空,說(shuō)明還沒(méi)有解析配置文件,不能往下處理.
echo "出錯(cuò): 請(qǐng)先調(diào)用 open_config_file filename 來(lái)解析配置文件."
return 1
fi
local option="$1"
local argument="$2"
case "${option}" in
-l) show_config_file ;;
-v) show_key_values ;;
-i) search_value_from_file "${argument}" ;;
-e) edit_config_file ;;
-a) append_key_value "${argument}" ;;
-d) delete_key_value "${argument}" ;;
*) return 127 ;;
esac
# 當(dāng)return語(yǔ)句不加上具體狀態(tài)碼時(shí),它會(huì)返回上一條執(zhí)行命令的狀態(tài)碼.
return
}
使用 parsecfg.sh 腳本的例子
假設(shè)有一個(gè) testparsecfg.sh 腳本,具體的代碼內(nèi)容如下:
#!/bin/bash
CFG_FILE="cfgfile.txt"
# 通過(guò) source 命令加載 parsecfg.sh 的腳本代碼
source parsecfg.sh
# 調(diào)用 open_config_file 函數(shù)解析配置文件
open_config_file "$CFG_FILE"
# 調(diào)用 handle_config_option 函數(shù)處理 -v 選項(xiàng).
# 該選項(xiàng)以鍵值對(duì)的形式列出所有配置項(xiàng).
handle_config_option -v
# 獲取 am 這個(gè)鍵名對(duì)應(yīng)的鍵值
value=$(get_value_by_key "am")
echo "The value of 'am' key is: $value"
# 使用 get_key_of_entry 函數(shù)從鍵值對(duì)中獲取鍵名.該函數(shù)
# 針對(duì)鍵值對(duì)自身進(jìn)行處理,所給的鍵值對(duì)可以不在配置文件中.
key=$(get_key_of_entry "a|adb logcat -b all")
echo "The key of 'a|adb logcat -b' is: $key"
這個(gè)腳本所調(diào)用的函數(shù)都來(lái)自于 parsecfg.sh 腳本。
這個(gè) testparsecfg.sh 腳本指定解析一個(gè) cfgfile.txt 配置文件。
該配置文件的內(nèi)容如下:
am|frameworks/base/services/core/java/com/android/server/am/
w|frameworks/base/wifi/java/android/net/wifi/
把 parsecfg.sh 腳本、testparsecfg.sh 腳本、和 cfgfile.txt 配置文件都放到同一個(gè)目錄下。
然后給這兩個(gè)腳本文件都添加可執(zhí)行權(quán)限。
執(zhí)行 testparsecfg.sh 腳本,具體結(jié)果如下:
$ ./testparsecfg.sh
key='am' value='frameworks/base/services/core/java/com/android/server/am/'
key='w' value='frameworks/base/wifi/java/android/net/wifi/'
The value of 'am' key is: frameworks/base/services/core/java/com/android/server/am/
The key of 'a|adb logcat -b' is: a
可以看到,在 testparsecfg.sh 腳本中通過(guò) source 命令引入 parsecfg.sh 腳本.
之后可以調(diào)用 parsecfg.sh 腳本里面的代碼來(lái)解析配置文件,非常方便。
如果多個(gè)腳本需要解析多個(gè)不同的配置文件,可以在各自腳本中引入 parsecfg.sh 腳本,然后提供不同的配置文件名即可。