Home / Alt manpages / fc-pattern(1)

  • fc-pattern(1)
  • User command
  • linux

Read fc-pattern Output Without Guessing

fc-pattern shows exactly how Fontconfig parsed your font request, before any matching or substitution happens. This walkthrough covers reading that output, trimming it to the fields you care about, and producing script-friendly text, using fontconfig 2.15.0 from Ubuntu's fontconfig package. Allow about ten minutes. You need a shell and a normal user account: none of this needs sudo or touches a configuration file.

1. Confirm what's actually installed

Check which binary you are about to run and note its version before trusting anything it prints. This matters because the local manual page is older than the installed program, and the help text is the more honest description of what the binary accepts.

$ command -v fc-pattern
/usr/bin/fc-pattern
$ fc-pattern --version
fontconfig version 2.15.0
$ fc-pattern --help
usage: fc-pattern [-cdVh] [-f FORMAT] [--config] [--default] [--verbose] [--format=FORMAT] [--version] [--help]

The help output continues with the pattern and element arguments. If command -v turns up a different copy, repeat the examples against that executable and treat its version as the truth. fc-pattern reads your account's Fontconfig configuration; it never writes to it.

Checkpoint

You know the executable and version before you start interpreting output.

2. Parse a family and style

Pass a pattern as a single shell argument. A colon splits the family from its properties in Fontconfig's pattern syntax. Ask for DejaVu Sans in Bold:

$ fc-pattern 'DejaVu Sans:style=Bold'
Pattern has 2 elts (size 16)
        family: "DejaVu Sans"(s)
        style: "Bold"(s)

That's a parsed pattern, not a list of installed fonts and not a match result. Two elements come back here, family and style; the (s) marker is Fontconfig's value-binding information. Keep quotes around any pattern containing spaces so the shell leaves it alone.

The short family syntax also works when it is unambiguous:

$ fc-pattern 'DejaVu Sans:bold:lang=en' family style lang
Pattern has 2 elts (size 16)
        family: "DejaVu Sans"(s)
        lang: en(s)

That result is a useful trap to know about: the word bold typed this way is not shown as a separate style element by the installed command. Use the explicit style=Bold form when the style property itself is what you are checking.

3. Trim the output to what you need

Add one or more element names after the pattern to keep a large pattern readable, which also makes two outputs easier to compare side by side:

$ fc-pattern 'DejaVu Sans:style=Bold' family style file
Pattern has 2 elts (size 16)
        family: "DejaVu Sans"(s)
        style: "Bold"(s)
  • file is missing on purpose. Parsing a pattern does not select an installed font file, so do not read a missing property as proof the font is unavailable.
  • Want the actual best match? That's a job for the separate fc-match command; inspect its result there instead.

An empty pattern is valid, and it is what you get by default when you omit the pattern argument:

$ fc-pattern
Pattern has 0 elts (size 0)
        (null):

That is not an error. It means there are no explicitly parsed elements to show.

4. Turn on substitutions deliberately

By default fc-pattern shows the pattern as typed. Two flags change that: --config (-c) runs Fontconfig's configuration substitution, and --default (-d) runs default substitution. Both can add or expand values, so leave them off when you want the literal request:

$ fc-pattern --default 'sans-serif' family style size
Pattern has 2 elts (size 16)
        family: "sans"(s)
        size: 12(f)(s)

Default substitution just added a size of 12. Configuration substitution goes further and can expand a generic family according to the machine's own setup:

$ fc-pattern --config 'sans-serif' family
Pattern has 1 elts (size 16)
        family: "DejaVu LGC Sans"(w) "Noto Sans"(w) "DejaVu Sans"(w) ...
  • (w) means weak. These are alternatives Fontconfig is willing to try.
  • (s) means strong. That is the value that wins.
  • Do not copy this family list into a deployment rule. It is host-specific and can run long.

If output changes after a package or configuration update, compare the version and the active Fontconfig configuration first.

Checkpoint

Decide whether you want the literal parsed request, the defaults, or the full substitution before you reach for -c or -d.

5. Get script-safe output with --format

When a human-readable dump is too noisy, use --format (-f). Request any property with %{property}, and put the newline inside the format string itself:

$ fc-pattern --format='family=%{family};style=%{style};file=%{file};\n' 'DejaVu Sans:style=Bold'
family=DejaVu Sans;style=Bold;file=;

That empty file value is expected for the same reason as before: this command parses a pattern, it does not match one to a font file. Format output is useful for logs and shell checks, but never assume every property exists; build in labels or delimiters so a missing value stays visible instead of silently shifting your fields.

Quote the format string so the shell leaves its punctuation alone. One value per line just means keeping the newline inside the string:

$ fc-pattern -f '%{family}\n%{style}\n' 'DejaVu Sans:style=Bold'
DejaVu Sans
Bold

6. Diagnose weird results without touching config

  1. Rerun without substitutions. See the literal pattern first.
  2. Add --default, then --config, separately. This isolates whether a value came from your input, the default rules, or the configuration.
  3. Use a field list or a format string. A long expansion can bury the one line you actually need.

An unrecognised element does not make the installed command exit non-zero; it just produces an empty pattern or no matching field. Check your spelling and test the same request without the element filter. And remember: fc-pattern alone never tells you whether a font is installed.

There is no recovery step here because every example is read-only. Do not edit system Fontconfig files just to make one diagnostic look different: changes there affect every other application on the machine, and should go through your distribution's normal package or administrator workflow with a tested rollback.

Done means

  • Confirmed the executable and version. You know exactly which fc-pattern and fontconfig build produced the output.
  • Told parsing apart from matching. You know fc-pattern shows a parsed request, not an installed font.
  • Selected specific properties. family, style and lang come back on demand.
  • Used --config and --default on purpose. Substitutions only show up when you ask for them.
  • Produced --format output. You can emit labelled values and spot an empty property.
  • Left no trace. No persistent or privileged change was made.