fd
fd copied to clipboard
[BUG] Full-path search and globbing leads to `fd` not exit on pipeline closing
Checks
- [X] I have read the troubleshooting section and still think this is a bug.
Describe the bug you encountered:
The shortest example I came up with is this:
> (fd . -p / | (exit))
# closes immediately, as expected
> (fd -g '*' -p / | (exit))
# hangs until the search is complete
I noticed it sometimes doesn't seem to happen when a **
pattern is used, only with single *
or with both *
and **
, but it's hard to establish a clear pattern.
Where it matters practically though is when piping into fzf. It will not abort the search even when fzf has exited.
One workaround I found for my use-case specifically is to make fzf invoke fd itself, i.e. FZF_DEFAULT_COMMAND='fd -gp "*" /' fzf
. Alternatively, something like fd -gp "*" / | { (fzf; exit) }
can also work.
Describe what you expected to happen:
fd
should exit the same way it does with regex search.
What version of fd
are you using?
9.0.0
Which operating system / distribution are you on?
Linux 6.1.72 x86_64
No LSB modules are available.
Distributor ID: NixOS
Description: NixOS 24.05 (Uakari)
Release: 24.05
Codename: uakari
Well, the deeper issue is that fd -p -g '*'
doesn't print anything. That's why it never quits, it never even writes anything to the pipe.
Oh wait, I guess that's on purpose. *
is only matching a single path component. It works with **
. See https://github.com/sharkdp/fd/issues/404#issuecomment-614044463 and https://github.com/sharkdp/fd/commit/47974b64795996dfe0adc06dadfe791efca25416
> (fd -gp '**' / | exit)
# exits normally
> (fd -gp '**' / | fzf)
# exits normally
> fd -gp '**' / | fzf
# exits normally
> (fd -gp '/home/me/**' / | exit)
# exits normally
> (fd -gp '/home/me/**' / | fzf)
# blocks
> fd -gp '/home/me/**' / | fzf
# blocks
> (fd -gpHL '/home/me/**' / | exit)
# forks??
> (fd -gpHL '/home/me/**' / | fzf)
# also forks
> fd -gpHL '/home/me/**' / | fzf
# blocks
Hmm I'm not sure what you mean by "forks". But as far as I can tell the behaviour of all those commands is within the expected range. fd
will only exit on a closed pipe if it actually tries to write while the pipeline is closed. For something like
> (fd -gp '/home/me/**' / | fzf)
it's quite possible that fd
prints all the matching paths while fzf
is still running, meaning the pipe is open. When you quit fzf
, fd
might still be searching the rest of /
, but it will never print anything again so it will never learn that the pipe is closed.
See https://github.com/sharkdp/fd/issues/472 for some related discussion about detecting closed pipes.
Thank you, I now undestand the problem. I didn't know how terminating the pipe works, my assumption was that a signal is sent when the receiving process exits, not when the sending process tries to write data.
By "forks" I mean fd starts to consume a lot of CPU and the process becomes independent of where I launched it from. I can even close the terminal and it's still running, as can be inspected in a process monitor utility.