0

I have a bash script that parses an xml file (name: myFile.xml) that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<params>
<username>jDoe</username>
<password>123abc</password>
<fullname>John Doe</fullname>
<email>johndoe@example.com</email>
<phone>1234567890</phone>
<country>Italy</country>
</params>

In that bash script, I parse each value of the xml file into a variable for further use. So far the bash script looks like that:

for i in $(xmlstarlet select --template --match "//params/*" --value-of "concat(name(),'=\"',text(),'\"')" -n myFile.xml)
do
   eval $i
done

#debugging:
echo $username
echo $fullname
echo $password

When I run this script

./myScript.sh

I get the following output:

./myScript.sh: eval: line 34: unexpected EOF while looking for matching `"'
./myScript.sh: eval: line 35: syntax error: unexpected end of file
./myScript.sh: eval: line 34: unexpected EOF while looking for matching `"'
./myScript.sh: eval: line 35: syntax error: unexpected end of file
jDoe

123abc

Apparently, because the tag <fullname> has a value of 2 words separated by space the script chokes. If I replace it's value "John Doe" with another (with no space) like: "JohnDoe" or "John_Doe" the script works fine!

Any suggestions as to how I can pass to a bash variable a value that contains space?

Of course, I would like to maintain the loop because 1. the actual script has too many parameters and 2. the parameters are not always the same (they vary from one xml file to another)...

(and to cut the long story short, this is what I would like to achieve: fullname="John Doe")

Theo Orphanos
  • 1,417
  • 1
  • 19
  • 27
  • See [DontReadLinesWithFor](http://mywiki.wooledge.org/DontReadLinesWithFor), and [BashFAQ #1](http://mywiki.wooledge.org/BashFAQ/001). – Charles Duffy Sep 05 '18 at 20:40
  • `while IFS='=' read -r key value; do printf -v "$key" %s "$value"; done < <(xmlstarlet ...)` is your friend. Well, not a very *good* friend, since it means a malicious file can set `LD_LIBRARY_PATH` or `PATH` or other security-sensitive variables -- if you're being careful, you'd put all the variables you extract from a file in an associative array. – Charles Duffy Sep 05 '18 at 20:42
  • @CharlesDuffy loop is necessary though... any ideas? – Theo Orphanos Sep 05 '18 at 20:43
  • I don't understand what you mean by your comment immediately above. Are you saying that you wish a loop *weren't* necessary? – Charles Duffy Sep 05 '18 at 20:43
  • @CharlesDuffy just saw your reply... Will try it! – Theo Orphanos Sep 05 '18 at 20:43
  • 1
    See my answer in https://stackoverflow.com/questions/38964946/reading-key-value-parameters-from-a-file-into-a-shell-script, which discusses security concerns (and ways to address them) in reading key/value content. Actually... adding that to the duplicate list. – Charles Duffy Sep 05 '18 at 20:44
  • 1
    ...also see [BashFAQ #48](http://mywiki.wooledge.org/BashFAQ/048), re: why `eval` is best avoided. And [BashFAQ #6](http://mywiki.wooledge.org/BashFAQ/006#Assigning_indirect.2Freference_variables), discussing better/safer ways to do indirect variable assignments. – Charles Duffy Sep 05 '18 at 20:46
  • 1
    Adding double quotes doesn't make `eval` safe, neither does forcibly adding single quotes -- think about what happens if you have a value of `$(rm -rf ~)'$(rm -rf ~)'` -- inside double quotes, both expansions get run by `eval`; inside single quotes, only the second one does; unquoted, only the first one does. – Charles Duffy Sep 05 '18 at 20:51
  • 1
    ...thus, I strongly recommend just taking those literal quotes out of your `xmlstarlet` expression. – Charles Duffy Sep 05 '18 at 20:55
  • @CharlesDuffy Thank you for taking the time to give me a thorough explanation. I 'll take my time to read the material you suggested, and will take it from there! – Theo Orphanos Sep 05 '18 at 21:11

0 Answers0