#601

grep -r without a path reads stdin, a missing path is silent, and -r follows symlinks like -R

Openasafyishopened 14d ago

just-bash version

3.6.0

Reproduction

cd /w
ln -s /w/real /w/link
grep -r alpha; echo "rc=$?"
grep -r alpha /nonexist; echo "rc=$?"
grep -rn alpha . | sort

How you run it

import { Bash } from "just-bash";

const bash = new Bash({
  files: { "/w/a.txt": "alpha\n", "/w/.hidden.ts": "alpha\n", "/w/real/s.txt": "alpha\n" },
});
const result = await bash.exec(script);

Expected behavior

GNU grep:

  • grep -r alpha with no file operand searches the working directory. It finds the three matches and exits 0.

  • grep -r alpha /nonexist prints grep: /nonexist: No such file or directory and exits 2.

  • grep -rn alpha . | sort gives:

    ./.hidden.ts:1:alpha
    ./a.txt:1:alpha
    ./real/s.txt:1:alpha

    -r follows symlinks only when they're on the command line (-R follows all of them), dot files are searched, and the ./ from the operand is kept.

Actual behavior

rc=1
rc=1
a.txt:1:alpha
link/s.txt:1:alpha
real/s.txt:1:alpha
  • The first command reads the empty stdin instead of the working directory.
  • The second exits 1 with nothing on stderr, which reads as "no match".
  • The third follows the symlink as -R would, skips .hidden.ts, and drops the ./ prefix.

We hit the silent missing path with an LLM agent. It mistyped a directory (entities/flowdefinition instead of entities/flowdefinitionview), got no output, and moved on as if nothing matched. Our tree also has a basis -> <id> symlink, so -r through it doubled every hit.

On main (9ab0e0d), rg reports a missing path since #584, but grep doesn't yet.

Environment

  • Runtime (Node, Bun, browser, CLI): Node
  • Runtime version: 26.8.2
  • Operating system: macOS 15
  • Bundler or framework, when relevant: none

Activity

0

No activity yet.