fzf: --filter for Non-Interactive Use in CI
fzf --filter <query> runs fzf in batch mode: it reads stdin, prints every line that fuzzy-matches the query in ranked order, and exits without any UI.
Plain fzf opens a full-screen interactive picker, which has no place in CI and will hang on a runner. The --filter flag is the non-interactive escape hatch.
What it does
Normally fzf reads a list on stdin, shows an interactive fuzzy-search UI, and prints the selection. With -f/--filter QUERY it skips the UI entirely: it filters the input lines by the query using its fuzzy algorithm and prints the ranked matches to stdout, top match first.
Common usage
# rank files by fuzzy match, take the best one
fd -e go | fzf --filter "mainsrv" | head -1
# exact-substring filtering
printf "alpha\nbeta\nbravo\n" | fzf -f beta --exact
# use as a fuzzy grep over a list
git branch --format='%(refname:short)' | fzf -f "rel"Options
| Flag | What it does |
|---|---|
| -f / --filter <query> | Non-interactive: print ranked matches and exit |
| --exact / -e | Exact-match mode instead of fuzzy |
| -i / +i | Force case-insensitive / case-sensitive |
| --no-sort | Keep input order instead of ranking |
| --tac | Reverse the input order |
| -d / --nth | Set delimiter / which fields to match against |
In CI
Only --filter is safe in CI; the interactive mode needs a TTY and will block forever on a runner. Pipe --filter output through head -1 to emulate "pick the top match". For deterministic selection, prefer --exact so ranking ties do not change which line wins.
Common errors in CI
A job that hangs at an fzf step ran interactive fzf with no TTY; it is waiting for keystrokes. Always use -f. "Failed to read /dev/tty" is the same problem surfacing as an error on some versions. "fzf: command not found" means it is not installed: apt-get install -y fzf, brew install fzf, or the git-based installer.