title: How to escape extended pathname expansion patterns in quoted expressions?
body: <p>In addition to the basic <code>*</code>, <code>?</code> and <code>[...]</code> patterns, the Bash shell provides extended pattern matching operators like <code>!(pattern-list)</code> ("match all except one of the given patterns"). The <code>extglob</code> shell option needs to be set to use them. An example:</p>
  
  <pre><code>~$ mkdir test ; cd test ; touch file1 file2 file3
  ~/test$ echo *
  file1 file2 file3
  ~/test$ shopt -s extglob  # make sure extglob is set
  ~/test$ echo !(file2)
  file1 file3
  </code></pre>
  
  <p>If I pass a shell expression to a program which executes it in a sub-shell, the operator causes an error. Here's a test which runs a sub-shell directly (here I'm executing from another directory to make sure expansion doesn't happen prematurely):</p>
  
  <pre><code>~/test$ cd ..
  ~$ bash -c "cd test ; echo *"
  file1 file2 file3
  ~$ bash -c "cd test ; echo !(file2)"  # expected output: file1 file3
  bash: -c: line 0: syntax error near unexpected token `('
  bash: -c: line 0: `cd test ; echo !(file2)'
  </code></pre>
  
  <p>I've tried all kinds of escaping, but nothing I've come up with has worked correctly. I also suspected <code>extglob</code> is not set in a sub-shell, but that's not the case:</p>
  
  <pre><code>~$ bash -c "shopt -s extglob ; cd test ; echo !(file2)"
  bash: -c: line 0: syntax error near unexpected token `('
  bash: -c: line 0: `cd test ; echo !(file2)'
  </code></pre>
  
  <p>Any solution appreciated!</p>