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.
Free DevOps eBooks, Videos, and more!
Regardless of where you are in your DevOps process, Linux Journal can help!
We offer here the DEFINITIVE DevOps for Dummies, a mobile Application Development Primer, and advice & help from the expert sources like:
- Linux Journal
- Be a Mechanic...with Android and Linux!
- New Products
- Users, Permissions and Multitenant Sites
- Flexible Access Control with Squid Proxy
- Security in Three Ds: Detect, Decide and Deny
- High-Availability Storage with HA-LVM
- Solving ODEs on Linux
- DevOps: Everything You Need to Know
- Tighten Up SSH
- Non-Linux FOSS: MenuMeters