Search code examples
regexbashag

Bash syntax errors when trying to run silver searcher


I'm trying to find instances of $ which are not followed by !.

That should necessitate $, escaped, which is \\$ and [^!] escaped which should be [^\\!] unless the [ and ] need to be escaped as well? Not sure about this one - don't know enough about bash just yet.

ag "\\$[^\!]"
bash: ^\!: syntax error: operand expected (error token is "^\!")

ag "\\$[^!]"
bash: !]: event not found

ag "\\$[^\\!]"
bash: ^\\!: syntax error: operand expected (error token is "^\\!")

ag "\\$[\\^\\!]"
bash: \\^\\!: syntax error: operand expected (error token is "\\^\\!")

ag "\\$[\^\!]"
bash: \^\!: syntax error: operand expected (error token is "\^\!")

These produce no results:

ag "\\$\\[\\^\\!\\]"
ag "\\$\\[\\^\\!\\]"
ag "\\$\[\\^\\!\]"
ag "\\$\[\^\!\]"
ag "\$\[\^\!\]"
ag "\\$\[\^\!\]"

Solution

  • When in doubt, use single quotes -- and character classes.

    ag '[$][^!]'
    
    • Single quotes prevent ! from being treated as a history expansion character (an instruction for bash to replace the command with one from shell history).
    • Single quotes prevent backslashes from being interpreted as part of an escape sequence, ensuring that they're passed through literally.
    • [$] is clearer than \$: If we were in a different kind of quoting context, the \ could potentially be consumed by that context; the square brackets are much less prone to misinterpretation. (If there's a file named $ and we're in a completely unquoted context, it could be treated as a glob expression... but that's a much smaller set of concerns than is pertinent for the backslash case).

    Also, given as you aren't aiming for finger compatibility with shells from the 1970s and 1980s, consider putting the following in your ~/.bashrc to make the ! character no longer special (in interactive shells only, making their behavior deviate from scripts):

    set +H