Skip to content
Latchkey

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

bash
# 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

FlagWhat it does
-f / --filter <query>Non-interactive: print ranked matches and exit
--exact / -eExact-match mode instead of fuzzy
-i / +iForce case-insensitive / case-sensitive
--no-sortKeep input order instead of ranking
--tacReverse the input order
-d / --nthSet 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.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →