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)

5
  • did you try escaping, like declare -a arrayN=('\-n' 'text')? Also try printf "%s\n" ${arrayN[@]}". Good luck. Commented Feb 20, 2014 at 17:25
  • @shellter within quotes, takes literally as \-n Commented Feb 20, 2014 at 17:31
  • @shellter, for printf, you need [*], otherwise each array element will print on a separate line. Commented Feb 20, 2014 at 17:51
  • 1
    Possible duplicate? Why is bash swallowing -e in the front of an array Commented Feb 20, 2014 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). Commented Feb 20, 2014 at 18:01

3 Answers 3

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[*]}"

Sign up to request clarification or add additional context in comments.

1 Comment

This printf invocation is simpler: printf "%s\n" "${array[*]}"
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.

1 Comment

I'm new to bash, I didn't think echo could have options. Thanks!
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...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.