ShellTree 6: Further Optimization by Removing Changes to IFS

This post is part of an educational series on building a shell script to graphically display the structure of a directory.


  1. We broke down Dem Pilafian’s one line command to display a tree of a directory
  2. We broke down Dem Pilafian’s script that uses the one line command
  3. We modified the one line to show files, as well as directories
  4. We built a recursive function that successfully prints out the graphical tree
  5. We Optimized the function by passing a string instead of an array


  1. Optimize the previously built recursive function.


  1. Understanding how to pass whitespace to functions

Getting the code

Run the following command:

git clone

In any step past step-0 you can get the code by issuing the following command but changing the step number to the appropriate one:

git checkout -f step-1

Step-15 Passing a String without Changing IFS

Last step we solved the problem of passing whitespace as a parameter to a function by changing the IFS. After some more research into the problem, (which resulted in the post about passing whitespace as parameter to a function) I found a way to do it without even having to change the IFS. We just have to use double quotes properly:

    local currentPath=$1 prefix="$2"
    local -a currentDir=($(ls $1))
    local -i lastIndex=$((${#currentDir[*]} - 1)) index

    for ((index=0; index<lastIndex; index++))
        printf "%s├─%s\n" "$prefix" ${currentDir[$index]}
        if [ -d "$currentPath/${currentDir[$index]}" ]; then
            listdir "$currentPath/${currentDir[$index]}" "$prefix""│ "

    if [ $lastIndex -ge 0 ]; then
        printf "%s└─%s\n" "$prefix" ${currentDir[$lastIndex]}
        if [ -d "$currentPath/${currentDir[$index]}" ]; then
            listdir "$currentPath/${currentDir[$index]}" "$prefix""  "
listdir $PWD ''

This gives the following:

[ahmed@amayem .git]$ ./../ 
│ ├─applypatch-msg.sample
│ ├─commit-msg.sample
│ ├─post-update.sample
│ ├─pre-applypatch.sample
│ ├─pre-commit.sample
│ ├─pre-push.sample
│ ├─pre-rebase.sample
│ ├─prepare-commit-msg.sample
│ └─update.sample
│ └─exclude
│ ├─HEAD
│ └─refs
│   ├─heads
│   │ └─master
│   └─remotes
│     └─origin
│       ├─HEAD
│       └─master
│ ├─info
│ └─pack
│   ├─pack-5d8c6d23ff13eded7a9d401ff91dae0f7fd6d00d.idx
│   └─pack-5d8c6d23ff13eded7a9d401ff91dae0f7fd6d00d.pack
  │ └─master
  │ └─origin
  │   ├─HEAD
  │   └─master

Looks good.

Next Steps

  1. Allow for flags to be used that are compatible with ls
  2. Deal with bad input
  3. Make it a user friendly bash script


  1. How to pass whitespace to functions

Ahmed Amayem has written 90 articles

A Web Application Developer Entrepreneur.