Peter Alfvin
Peter Alfvin

Reputation: 29409

Understanding bash echo

I'm not understanding bash's echo command. Can you explain why echo $a just outputs a newline in the following?

MacbookAir1:so1 palfvin$ a='[]'
MacbookAir1:so1 palfvin$ echo $a

MacbookAir1:so1 palfvin$ echo "$a"
[]
MacbookAir1:so1 palfvin$ echo '[]'
[]
MacbookAir1:so1 palfvin$ 

I'd particularly appreciate a reference to some documentation explaining this.

The bash version is GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)

Update: Output of examination of IFS after resetting per comment thread, is as follows:

MacbookAir1:~ palfvin$ echo "$IFS" | od -c
0000000       \t  \n  \n                                                
0000004
MacbookAir1:~ palfvin$ echo "$IFS" | od -h
0000000      0920    0a0a                                                
0000004

Upvotes: 3

Views: 175

Answers (2)

Gordon Davisson
Gordon Davisson

Reputation: 125808

Having the nullglob shell option set can cause this. [] is a glob pattern that matches any of the characters between [ and ], which is to say nothing. Normally, if the shell finds a pattern that doesn't match anything, it just leaves it alone; but with nullglob it's removed :

$ a='[]'
$ echo $a
[]
$ shopt -s nullglob
$ echo $a

$ 

From the Filename Expansion section of the bash manual:

After word splitting, unless the -f option has been set (see The Set Builtin), Bash scans each word for the characters ‘*’, ‘?’, and ‘[’. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern. If no matching file names are found, and the shell option nullglob is disabled, the word is left unchanged. If the nullglob option is set, and no matches are found, the word is removed.

Upvotes: 4

Jonathan Leffler
Jonathan Leffler

Reputation: 753970

What's your $IFS set to?

When I set it to IFS='[]', then I can reproduce your result (on a MacBook Pro running Mavericks 10.9.1 and using Bash 3.2.51(1)). When IFS is set to spaces, the problem does not reproduce:

$ echo []
[]
$ x=[]
$ echo $x
[]
$ IFS='[]'
$ echo $x

$

Incidentally, bash -v invokes verbose mode; it echoes the shell script as it processes it. You might still be in a sub-shell, which shouldn't matter much until you try to exit from it, when you'll find yourself in a long-forgotten parent shell instead of having a closed window.

Upvotes: 1

Related Questions