From c060af3c817b3ce9bffd435cd4485122af44b951 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 1 Feb 2015 12:39:27 +0100 Subject: [PATCH] First implementation --- README.md | 63 +++++++++++++++++++++++++++++++++++ bash-ini-parser | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ test/file.ini | 17 ++++++++++ test/test.sh | 25 ++++++++++++++ test/testfile.sh | 22 +++++++++++++ 5 files changed, 213 insertions(+) create mode 100644 README.md create mode 100644 bash-ini-parser create mode 100644 test/file.ini create mode 100755 test/test.sh create mode 100755 test/testfile.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..845bd13 --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +## bash-ini-parser + +A ini file parser for bash relying only on builtins + +### Using + +You must copy bash-ini-parser on your project and source it + + $ source bash-ini-parser + +or + + $ . source bash-ini-parser + +It will declare functions per section called cfg.section.
with variable declaration inside so you can access its values using + + $ cfg.section.
+ $ echo $var + +### test it + +Goto test directory and launch test.sh + + $ cd test + $ ./test.sh + +Inspect its code, reuse on your scripts + +If you want to test your existing ini file use testfile.sh + + $ testfile.sh >customfile.ini< sectionname varname + +e.g.: + + $ ./testfile.sh file.ini sec1 var4 + show parsed file.ini + [sec1] + var1="foo" + var2="hoge" + var3="fuga" + var4="pivo" + [sec2] + var1="bar" + var2="foo" + var3="eco" + var4="piyo baz qux" + var5="foo" + var6="hoge" + + var4 value is "pivo" + +### Drawbacks + +This is more a hack than a reliable parser, so keep in mind things like + + - multiword value vars will be arrays so you must access it as `${var[*]}` + - changing from section to section will not erase previous var declarations + +For a trusted parser (but based on python) checkout [crudini](https://github.com/pixelb/crudini) + +### Credits + +This is just an enhacement from http://theoldschooldevops.com/2008/02/09/bash-ini-parser diff --git a/bash-ini-parser b/bash-ini-parser new file mode 100644 index 0000000..89d812a --- /dev/null +++ b/bash-ini-parser @@ -0,0 +1,86 @@ +# +# based on http://theoldschooldevops.com/2008/02/09/bash-ini-parser/ +# + +function debug { + return #abort debug + echo $* + echo "${ini[*]}" + echo +} + +function cfg_parser { + ini="$(<$1)" # read the file + ini="${ini//[/\\[}" # escape [ + debug + ini="${ini//]/\\]}" # escape ] + debug + IFS=$'\n' && ini=( ${ini} ) # convert to line-array + debug + ini=( ${ini[*]//;*/} ) # remove comments with ; + debug + ini=( ${ini[*]/ =/=} ) # remove tabs before = + debug + ini=( ${ini[*]/# /} ) # remove init tabs #TODO: remove all not just one + debug + ini=( ${ini[*]/# /} ) # remove init space #TODO: remove all not just one + debug + ini=( ${ini[*]/= /=} ) # remove tabs after = + debug + ini=( ${ini[*]/ = /=} ) # remove anything with a space around = + debug + ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix + debug + ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1) + debug + ini=( ${ini[*]/=/=\( } ) # convert item to array + debug + ini=( ${ini[*]/%/ \)} ) # close array parenthesis + debug + ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick + debug + ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2) + debug + ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis + debug + ini[0]="" # remove first element + debug + ini[${#ini[*]} + 1]='}' # add the last brace + debug + eval "$(echo "${ini[*]}")" # eval the result +} + +function cfg_writer { + IFS=' '$'\n' + fun="$(declare -F)" + fun="${fun//declare -f/}" + for f in $fun; do + [ "${f#cfg.section}" == "${f}" ] && continue + item="$(declare -f ${f})" + item="${item##*\{}" + item="${item/\}}" + item="${item%)*}" + item="${item});" + vars="" + while [ "$item" != "" ] + do + newvar="${item%%=*}" + vars="$vars $newvar" + item="${item#*;}" + done + eval $f + echo "[${f#cfg.section.}]" + for var in $vars; do + eval 'local length=${#'$var'[*]}' + if [ $length == 1 ] + then + echo $var=\"${!var}\" + else + echo ";$var is an array" + eval 'echo $var=\"${'$var'[*]}\"' + fi + done + done +} + +# vim: filetype=sh diff --git a/test/file.ini b/test/file.ini new file mode 100644 index 0000000..7781239 --- /dev/null +++ b/test/file.ini @@ -0,0 +1,17 @@ +;seccion one: clean whitespace +[sec1] + var1=foo + var2 =hoge + var3 = fuga + var4= pivo +[sec2] +;this is the variable we want +var1=bar +var2=foo +var3=eco +;this is a multiword value +var4="piyo baz qux" +;this is an array +var5=foo bar baz hoge +var6=hoge + diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..110d356 --- /dev/null +++ b/test/test.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +source ../bash-ini-parser + +TEST_FILE="file.ini" +# parse the config file called 'myfile.ini' +cfg_parser "$TEST_FILE" + +# show parsed ini file +echo show file parsed +cfg_writer +echo + +echo show some results +# enable section called 'sec2' (in the file [sec2]) for reading +cfg.section.sec2 + +# read the content of the variable called 'var2' (in the file +# var2=XXX). If your var2 is an array, then you can use +# ${var[index]} +echo "var2 value is \"$var2\"" +echo "var5[1] value is \"${var5[1]}"\" +echo "var5[*] value is \"${var5[*]}"\" +echo "var4 value is \"$var4"\" + diff --git a/test/testfile.sh b/test/testfile.sh new file mode 100755 index 0000000..0596780 --- /dev/null +++ b/test/testfile.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +source ../bash-ini-parser + +TEST_FILE="$1" +TEST_SECTION="$2" +TEST_VALUE="$3" + +# parse the config file +cfg_parser "$TEST_FILE" + +# show parsed ini file +echo show parsed $TEST_FILE +cfg_writer +echo + +# enable section selected +cfg.section.$TEST_SECTION + +# show value of section selected +echo "$TEST_VALUE value is \"${!TEST_VALUE}\"" +