A basic for loop
The Bash for loop splits using a whitespace (space, tab or newline). This allows you to easily iterate over a glob of values, as follows (this particular example uses a glob of filenames, taken from a backup script that requires a list of files to exclude from the backup):
Script:
#!/bin/bash vals='/mnt /dev /proc /sys /tmp /usr/portage /var/tmp' for i in $vals; do echo $i; done
Output:
/mnt /dev /proc /sys /tmp /usr/portage /var/tmp
The problem
A problem arises when one of the values in the glob needs to contain a space. Take the following example:
#!/bin/bash vals='/mnt /var/lib/vmware/Virtual Machines /dev /proc /sys /tmp /usr/portage /var/tmp' for i in $vals; do echo $i; done
Output:
/mnt /var/lib/vmware/Virtual Machines /dev /proc /sys /tmp /usr/portage /var/tmp
"/var/lib/vmware/Virtual Machines" is split because it contains a space, which would obviously be a major problem if you were attempting to do something with each file location rather than just echoing it.
The IFS internal variable
One way around this problem is to change Bash's internal IFS (Internal Field Separator) variable so that it splits fields by something other than the default whitespace (space, tab, newline), in this case, a comma.
#!/bin/bash IFS=$',' vals='/mnt,/var/lib/vmware/Virtual Machines,/dev,/proc,/sys,/tmp,/usr/portage,/var/tmp' for i in $vals; do echo $i; done unset IFS
Output:
/mnt /var/lib/vmware/Virtual Machines /dev /proc /sys /tmp /usr/portage /var/tmp
It's best to unset IFS after you've done your work, with unset IFS, so that it returns to its default value. This will avoid any potential problems that could arise in the rest of your script.
References
- 9.1. Internal Variables from the Advanced Bash-Scripting Guide
- Debian Reference Chapter 8 - Debian tips