3

When the first element of an array is '-n' or '-e', has strange behavior, looks like some times the first element is missing.

My script test.sh:

#!/bin/bash
declare -a arrayP=('-p' 'text')
echo "arrayP"
echo ${arrayP[@]}
echo "${arrayP[@]}"
echo "'${arrayP[@]}'"
echo " ${arrayP[@]}"

echo ""

declare -a arrayN=('-n' 'text')
echo "arrayN"
echo ${arrayN[@]}
echo "${arrayN[@]}"
echo "'${arrayN[@]}'"
echo " ${arrayN[@]}"

echo ""

declare -a arrayE=('-e' 'text')
echo "arrayE"
echo ${arrayE[@]}
echo "${arrayE[@]}"
echo "'${arrayE[@]}'"
echo " ${arrayE[@]}"

Execution results:

root@host:~# ./test.sh
arrayP:
-p text
-p text
'-p text'
 -p text

arrayN:
texttext'-n text'
 -n text

arrayE:
text
text
'-e text'
 -e text
root@host:~#

arrayP works as expected, but arrayN and arrayE, each one behaves in different way.

I'm guessing -n, -e and probably others, have special meaning in some way, I cold not find any related information.

I'm using GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)

luistar15
  • 163
  • 1
  • 9
  • did you try escaping, like `declare -a arrayN=('\-n' 'text')`? Also try `printf "%s\n" ${arrayN[@]}"`. Good luck. – shellter Feb 20 '14 at 17:25
  • @shellter within quotes, takes literally as `\-n` – luistar15 Feb 20 '14 at 17:31
  • @shellter, for printf, you need `[*]`, otherwise each array element will print on a separate line. – glenn jackman Feb 20 '14 at 17:51
  • 1
    Possible duplicate? [Why is bash swallowing -e in the front of an array](http://stackoverflow.com/q/21150793/27581) – Michael Kropat Feb 20 '14 at 17:52
  • @glennjackman : yes, I thought the `"%s\n"` would provide a good debugging view of what is happening (but didn't have time to test it, hence a comment, rather than an answer). – shellter Feb 20 '14 at 18:01

3 Answers3

4

The problem is with echo, not with the array itself. If you print the array as separate arguments, -n and -e will be interpreted by echo as options (print without newline, and print with special escape characters, respectively). See man echo for a more detailed explanation.

You could use something like echo '' ${arrayN[@]} to prevent that, but you'll end up with an additional space at the beginning of the line.

If you're not bound to using echo, you can print it correctly by using cat <<<${arrayN[@]} or printf "%s\n" "${arrayN[*]}"

Sir Athos
  • 9,403
  • 2
  • 22
  • 23
3

-n and -e are options for echo. -n makes it not print a newline while -e makes it interpret escape sequences. In some cases, when you expand the array, bash reads these as options to echo. Eg:

$ echo -n hello          # no newline
hello$ echo "-n hello"   # string "-n hello"
-n hello
$ echo -e "\n"           # extra newline


$ echo "-e \n"           # string "-e \n"
-e \n

-E will also give similar behaviour.

One alternative is to use printf %s as per Sir Athos's answer.

Graeme
  • 2,971
  • 21
  • 26
2

Also, note this interesting behaviour:

$ array=('-n' 'text')

$ echo "${array[@]}"      # array expands into individual elements
text                      # no newline

$ echo "${array[*]}"      # array printed as a single string.
-n text

From a bash prompt, type help echo. Would be nice for echo to have a -- option...

glenn jackman
  • 238,783
  • 38
  • 220
  • 352