Hi everyone,

I recently wrote a script and I needed to use arrays.

Unfortunately, there are no arrays in the POSIX shell specification. But, after some research I found a way to use pseudo-arrays.

The first trick is to use the set command which permits to modify the values of the positional parameters. You will therefor be able to get the number of elements ($#), access any items (for the n-th item: $n) or iterate through them. The only thing I don't know is how to change the value of one of them.

The second trick is to properly quote the various elements you want to put in it. To do that I wrote a small function (which I won't describe here) which is able substitute a substring by another one in a string. I used this function to replace each occurrence of a single quote by “a single quote + an escaped single quote + a single quote” in my items and I enclosed them between two single quotes.

Here is an example of how using it.

  1. #!/bin/sh
  2.  
  3. . jfsh.sh # Contains the quote function (and subst which is used by it)
  4.  
  5. print_arrays()
  6. {
  7. local array entry
  8.  
  9. for array
  10. do
  11. eval "set -- $array" # Loads the array contained in $1
  12.  
  13. printf '%d elements\n' $#
  14. for entry
  15. do
  16. printf ' “%s”\n' "$entry"
  17. done
  18. done
  19. }
  20.  
  21. reverse_array()
  22. {
  23. local entry result
  24.  
  25. eval "set -- $1"
  26.  
  27. for entry
  28. do
  29. result="$(quote "$entry") $result"
  30. done
  31.  
  32. printf '%s\n' "$result"
  33. }
  34.  
  35. array1="$(quote 1 "second element" "third one")"
  36.  
  37. # This array will contains the filenames of every files in this directory.
  38. array2="$(quote *)"
  39.  
  40. # We can apply a function on array1.
  41. array3="$(reverse_array "$array1")"
  42.  
  43. # Let's print the various arrays.
  44. print_arrays "$array1" "$array2" "$array3"

The file “jfsh.sh” is available on github.