Bash: Passing Whitespace as Parameters to Functions

This post will deal with how to pass whitespace as a parameter to a function in bash shell scripting.

Pre-requisites

  1. Understanding bash whitespace quotation and backslash escaped characters
  2. Understanding IFS and how to modify it and its effects

Setup

Let’s make a shell script. In your favourite editor type

#!/bin/bash

And save it somewhere as whitespace.sh. Now we need to make it executable as follows:

[ahmed@amayem ~]$ chmod +x ./whitespace.sh 
[ahmed@amayem ~]$ ./whitespace.sh 

Looks good so far.

Building the Function

Let’s make a function that will accept a whitespace character and see if it can output it:

whitespaceAccept()
{
    echo -n $1 | od -abc
    echo -n $2 | od -abc
    echo -n $3 | od -abc
}

whitespaceAccept " " "  " $'n'

I decided to use od because it gives us a lot of extra information. To see other ways to output whitespace characters check here. When calling the function I sent three parameters: the first is a space, the second is a horizontal tab (which you can’t really see, but it is there) and the third is a new line. I intentionally used different quotation methods to show that they all work.

Failing to Receive with no Quotes

whitespaceAccept()
{
    # local first="$1"
    echo -n $1 | od -abc
    echo -n $2 | od -abc
    echo -n $3 | od -abc
}

whitespaceAccept " " "  " $'n'

Gives us the following:

Ahmeds-MacBook-Pro:shell-tree ahmedamayem$ ./whitespace.sh 
Ahmeds-MacBook-Pro:shell-tree ahmedamayem$

The whitespace was not successfully received. The reason for this is because when variables are expanded into whitespace, bash considers the whitespace to be part of the IFS, which is by default <space><tab><newline>, hence it ignored the passed parameters. For more information on IFS check here. If we want to use unquoted variables then we have to modify the IFS so that bash would not see such characters as field separators.

Receiving with no Quotes by Changing the IFS

oldIFS=$IFS
IFS=$''

whitespaceAccept()
{
    # local first="$1"
    echo -n $1 | od -abc
    echo -n $2 | od -abc
    echo -n $3 | od -abc
}

whitespaceAccept " " "  " $'n'
IFS=$oldIFS

Gives us the following:

Ahmeds-MacBook-Pro:shell-tree ahmedamayem$ ./whitespace.sh 
0000000   sp                                                            
      040                                                            

0000001
0000000   ht                                                            
          011                                                            
          t                                                            
0000001
0000000   nl                                                            
          012                                                            
          n                                                            
0000001.

We have success.

Failing to Receive with Single Quotes

whitespaceAccept()
{
    # local first="$1"
    echo -n '$1' | od -abc
    echo -n '$2' | od -abc
    echo -n '$3' | od -abc
}

whitespaceAccept " " "  " $'n'

Gives us the following:

Ahmeds-MacBook-Pro:shell-tree ahmedamayem$ ./whitespace.sh 
0000000    $   1                                                        
          044 061                                                        
           $   1                                                        
0000002
0000000    $   2                                                        
          044 062                                                        
           $   2                                                        
0000002
0000000    $   3                                                        
          044 063                                                        
           $   3                                                        
0000002

This is because as explained here single quotes take away the special meaning of $, and so od prints out the $ and the number.

Receiving with Double Quotes

whitespaceAccept()
{
    # local first="$1"
    echo -n "$1" | od -abc
    echo -n "$2" | od -abc
    echo -n "$3" | od -abc
}

whitespaceAccept " " "  " $'n'

Gives us the following:

Ahmeds-MacBook-Pro:shell-tree ahmedamayem$ ./whitespace.sh 
0000000   sp                                                            
      040                                                            

0000001
0000000   ht                                                            
          011                                                            
          t                                                            
0000001
0000000   nl                                                            
          012                                                            
          n                                                            
0000001

Success. The reason for this is because the double quotes allow the $ to keep its special meaning and so the $1 expands to the whitespace that was passed. The expanded whitespace is expanded inside the double quotes, which maintains it literally and protects it from being understood as field separators (part of the IFS).

References

  1. Understanding bash whitespace quotation and backslash escaped characters
  2. Understanding IFS and how to modify it and its effects

Ahmed Amayem has written 90 articles

A Web Application Developer Entrepreneur.