Bash: Preserving Whitespace Using set and eval
If you don't care much about whitespace bash is great: it normally turns multiple whitespace characters into one and it breaks things into words based on white space. If on the other hand you'd like to preserve whitespace bash can be a bit difficult at times. A trick which often helps is using a combination of bash's eval and set commands.
Let's say that you're building a list of items where each item may contain significant spaces, say something like:
#!/bin/bash items= for i in "$@" do items="$items \"$i\"" done for i in $items do echo $i done
But when you run this and try to use the items from the saved list you don't quite get what you expected:
$ sh t1.sh "ab cd" "ef gh" "ab cd" "ef gh"
One solution is to do the following:
#!/bin/bash items= for i in "$@" do items="$items \"$i\"" done eval set -- $items for i in "$@" do echo $i done
Which produces the desired result:
$ sh t2.sh "ab cd" "ef gh" ab cd ef gh
The important line is:
eval set -- $items
The set command takes any arguments after the options (here "--" signals the end of the options) and assigns them to the positional parameters ($0..$n). The eval command executes its arguments as a bash command.
If you do this without the eval command you'll get the same result as the first example. By passing the set command to eval bash will honor the embedded quotes in the string rather than assume they are part of the word.
If you run this script you can see a bit more of what bash is doing:
#!/bin/bash items= for i in "$@" do items="$items \"$i\"" done set -x set -- $items set +x echo '====' set -x eval set -- $items set +x
$ sh t3.sh "ab cd" "ef gh" + set -- '"ab' 'cd"' '"ef' 'gh"' + set +x ==== + eval set -- '"ab' 'cd"' '"ef' 'gh"' ++ set -- 'ab cd' 'ef gh' + set +x
Mitch Frazier is an Associate Editor for Linux Journal.
- Promise Theory—What Is It?
- New Products
- Tech Tip: Really Simple HTTP Server with Python
- Integrating Trac, Jenkins and Cobbler—Customizing Linux Operating Systems for Organizational Needs
- Validate an E-Mail Address with PHP, the Right Way
- Virtualization Poll
- Linux In Government: Interoperability
- Raspberry Pi: the Perfect Home Server
- Learn GNU/Linux the Fun Way