This is a read-only archive!

Darn you, failglob

I turned on bash_completition today. Couldn't quite remember why I had it turned off. I quickly realized though. bash would fail on any filename with a square-bracket in it. It looks something like this:

~ $ touch 'test [1]'
~ $ ls<I HIT TAB HERE> bash: no match: test [1]
~ $

In other words, hitting TAB to tab-complete filenames would dump me back to a command prompt giving me that unhelpful error message, and I'd have to start the whole command over.

The problem was that I had this in my ~/.bashrc:

shopt -s failglob

I can't for the life of me remember why that was in my .bashrc. Clearly it wasn't doing anything I never had any use for, because this is the first time I got this "bash: no match" error. Removing that line makes bash_completion work again though, so all is well.

This was a nightmare to debug too. Google was totally useless. I tracked it down to the _filedir function in /etc/bash_completition, and then it was trial-and-error. Next time I'm going to start off loading a clean login environment before I bother checking the system scripts for things. I did also learn that set -v in a bash script makes it dump every line it executes to STDIN as it's executing them.

May 05, 2007 @ 1:14 PM PDT
Cateogory: Programming

2 Comments

Richard Neill
Quoth Richard Neill on October 31, 2007 @ 8:59 AM PDT

I can tell you why failglob is good and why it is bad. Consider a shell script, running:

i=0; for file in ZZZ; do let i++; done; echo "There are $i files matching '.ZZZ'"

[This should count the number of files ending in the .ZZZ extension]

What happens if you haven't got any files ending in .ZZZ?

By default, bash will fail to expand (glob) ".ZZZ", and will fall-back to evaluating it as a literal '.ZZZ'.

You will get the wrong answer, i.e. 1.

failglob will make bash throw an error. nullglob is probably what you want.

Brian
Quoth Brian on October 31, 2007 @ 12:30 PM PDT

Yeah, that makes sense. Thanks for clearing that up.

When I set nullglob, if I do ls *ZZZ it actually does ls if the glob matches nothing. That seems kind of dangerous for any command that defaults to doing something on all files if the file list is missing. Globs are so messy. Can't live with them, can't live without them.