2

In bash, if you have an array arr and you want to print all its values, the command

echo ${arr[@]}

will do the trick. In sh however, this command gives a bad substitution error. What is an alternative command(s) for this task in sh?

danielmhanover
  • 3,094
  • 4
  • 35
  • 51

2 Answers2

3

There is no such thing as a general-purpose array in the POSIX sh specification. The closest thing you have available for an arbitrary variable is a string separated by some delimiter; usually whitespace separated, but can be separated by other characters if the elements themselves can contain spaces.

$@ can be treated as an array in POSIX sh, but it's a bit limited due to the fact that there's only one such variable. You can change the value of $@ with set, so you can do the following:

$ set -- one "two three" four
$ echo "$#"
3
$ echo "$1"
one
$ echo "$2"
two three
$ echo "$3"
four
$ printf '"%s" "%s" "%s"\n' "$@"
"one" "two three" "four"
Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • 1
    I wouldn't say that a string is [the closest thing](http://stackoverflow.com/questions/12711786/bash-convert-command-line-arguments-into-array/12711837#12711837) – kojiro Feb 05 '14 at 00:34
  • Are you sure you can have null characters in a string in `sh`? Even if you can, I doubt that it's a good idea. (The only way I managed to do it in bash is `s=$'foo\0bar`, and I don't think POSIX sh has that feature.) It's common to use `:` as a delimiter (see `$PATH` et al). – Keith Thompson Feb 05 '14 at 01:21
  • @KeithThompson Hmm, you may be right. `\0` is relatively common to delimit records in a pipe (`find . -name *.c -print0 | xargs -0 grep something`), but you're right, I can't think of any way using standard shell features to get them into a string. – Brian Campbell Feb 05 '14 at 01:39
  • @kojiro Yeah, I thought of mentioning how `$@` can act like an array in standard `sh`, but thought it would confuse the issue since it's not really a general purpose variable. I'd forgotten about using `set` to manipulate `$@` such that you can actually have a single general purpose array (which is still fairly limited). – Brian Campbell Feb 05 '14 at 01:43
  • I've used `$'\g'` (the BEL character) as a delimiter to reasonably good effect in some scripts. There's no doubt it's a hack, but it's nevertheless unlikely to occur by accident. – kojiro Feb 05 '14 at 03:00
0

Couple questions:
- Can you provide any further details on the script and how the array is being initialized?
- Are you sure that you're actually using sh? On some system /bin/sh is a symlink something else like bash.

ls -l /bin/sh
lrwxrwxrwx 1 root root 4 2013-06-04 19:52 /bin/sh -> bash

I would recommend http://www.tutorialspoint.com/unix/unix-using-arrays.htm as a starting point.

Ryan Tennill
  • 156
  • 7
  • Very few systems have an actual shell named `sh` these days. The POSIX shell is simply a specification that any shell can satisfy, so that `/bin/sh` is a link to a concrete shell such as `bash`, `dash`, or `zsh`. – chepner Feb 05 '14 at 00:42