Skip to content

Inconsistent behaviour between configuration file and passing arguments on the commandline #3428

Description

@fenree

Unsure whether to tag this is a bug or a feature request or a bit of both.

Exposition

Running Arch Linux fully up to date, everything is tested using bash --norc

zephyr@archlinux
~ $ bash --norc
bash-5.3$ bash --version
GNU bash, version 5.3.9(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
bash-5.3$ rg --version
ripgrep 15.1.0

features:+pcre2
simd(compile):+SSE2,-SSSE3,-AVX2
simd(runtime):+SSE2,+SSSE3,+AVX2

PCRE2 10.45 is available (JIT is available)

The issue (part 1)

bash-5.3$ cat $RIPGREP_CONFIG_PATH
-g '!.org/*'
bash-5.3$ rg 67
rg: No files were searched, which means ripgrep probably applied a filter you didn't expect.
Running with --debug will show why files are being skipped.
bash-5.3$ mv $RIPGREP_CONFIG_PATH{,.backup}
bash-5.3$ rg -g '!.org/*' 67 | head -n 1
rg: failed to read the file specified in RIPGREP_CONFIG_PATH: /home/zephyr/.rgrc: No such file or directory (os error 2)
org/git.org:    ':(exclude)*mx[678]*'          \

If i use single quotes in my config file it will not work. This is a problem because in bash, which is the shell that is most commonly used as it is the default, you cannot use the -g option to exclude a directory without using singlequotes. This is because the exclamation mark is a special character in bash with default settings:

bash-5.3$ rg -g !.org/*
bash: !.org/: event not found

This also occurs in zsh actually

zephyr @ archlinux
~ $ zsh
archlinux% rg -g !.org/* pat
zsh: event not found: .org/

Bash users, are then going to use singlequotes every single time, because without them it doesn't work.
Ofcourse this happens because when ripgrep reads arguments on the commandline it expects the shell to have already stripped the quotes, as a POSIX shell will do that. However when it reads from a file, those arguments are not intercepted by a shell at all, so not only are they unnecessary, but they also do not get removed. This however, means that ripgrep should be able to handle that case. Instead what happens is that it will tell you to use the debug flag, which only really tells you that the glob is ignoring every file, but not why the glob is ignoring them.

The issue (part 2)

This is inconsistent and confusing behaviour. What makes it a really big issue is that the manpage doesn't mention this behaviour, it just lists an example without quotes.

     ripgrep  will  look for a single configuration file if and only if
     the RIPGREP_CONFIG_PATH environment variable is set  and  is  non-
     empty.  ripgrep will parse arguments from this file on startup and
     will behave as if the arguments in this file were prepended to any
     explicit  arguments  given  to  ripgrep  on the command line. 

     ...

     The same applies to using globs. This:

         --glob=!.git

     or this:

         --glob
         !.git

     would behave identically to the following command:

         rg --glob '!.git' foo

     The bottom line is that every shell argument needs to  be  on  its
     own line. So for example, a config file containing

No mention of this behaviour at all in the manpage. People who don't know exactly which order shells parse things and hand them off to commands in, could spend quite a while scratching their heads with this one. One could argue whether the solution is making the behaviour consistent, i. e. ripgrep being able to strip quotes from the configuration file arguments like the shell would, or maybe one could just add a warning for this edge case, or even just tweak the manpage so atleast the manpage doesn't outright state that the configuration files arguments behave as though they are prepended to the explicit arguments on the commandline, as that is false and misleading.

Happy to provide any other details if necessary.
Thank you for reading and thank you for your time. Ripgrep is awesome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions