fc-scan digs through a font file or a whole directory tree and prints a pattern for every face it finds. Allow about ten minutes. You need Fontconfig and a readable font path; none of the commands below needs sudo, and the scan never edits the input.
Worth knowing before you start: this machine's local fc-scan(1) page is an older generated page dated 15 January 2009. It documents recursive scanning and -f, but not every option the installed 2.15.0 binary actually has. Where the two disagree, trust the installed help and behaviour.
Start with read-only version and help checks, to confirm which executable and package you are about to use:
$ command -v fc-scan
/usr/bin/fc-scan
$ fc-scan --version
fontconfig version 2.15.0
$ dpkg-query -W -f='${Package} ${Version}\n' fontconfig
fontconfig 2.15.0-1.1ubuntu2
$ fc-scan --help
usage: fc-scan [-bcVh] [-f FORMAT] [-y SYSROOT] [--brief] [--format FORMAT] [--version] [--help] font-file...
Checkpoint: If command -v finds nothing, install or repair Fontconfig through your normal package-management process. A manpage on disk does not prove the matching executable is on your PATH.
Give the command a font file and it prints a Fontconfig pattern for each face it finds. A TrueType collection or another multi-face file can produce more than one pattern from a single path:
$ fc-scan /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
Pattern has 28 elts (size 32)
family: "DejaVu Sans"(s)
style: "Book"(s)
file: "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"(s)
index: 0(i)(s)
outline: True(s)
scalable: True(s)
The complete pattern is deliberately verbose: family and style names, weight, width, language coverage, file path, face index and format-specific properties can all show up. Treat it as diagnostic output, not a stable report; fields vary with the font, the Fontconfig version and the configuration.
Checkpoint: Confirm the path and face you expected. file is the scanned path; index identifies a face within a collection or other multi-face resource.
Pass a directory to inspect a whole font tree, subdirectories included:
$ fc-scan /usr/share/fonts/truetype/dejavu > /tmp/dejavu-font-scan.txt
$ sed -n '1,12p' /tmp/dejavu-font-scan.txt
Pattern has 28 elts (size 32)
family: "DejaVu Math TeX Gyre"(s)
familylang: "en"(s)
style: "Regular"(s)
> truncates an existing destination before fc-scan even starts; use a new name or copy the old report first.None of this touches configuration. The scan reads the supplied path and prints patterns; it does not install a font or make anything available to applications.
Use --format or its short form -f when another program needs specific pattern fields. Put a newline in the format so each face lands on one line:
$ fc-scan --format='%{family}\t%{style}\t%{file}\n' /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
DejaVu Sans Book /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
%{family}, %{style} and %{file} ask for pattern properties. Quote the format so the shell passes the braces, tabs and newline marker through unchanged. If a property is absent or multi-valued, the result depends on that pattern; do not read an empty field as proof the font lacks metadata.
For a quick readable check, the installed 2.15.0 binary also accepts --brief:
$ fc-scan --brief /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
Pattern has 26 elts (size 32)
family: "DejaVu Sans"(s)
style: "Book"(s)
Brief output is still a Fontconfig pattern, not a promise of one line or a fixed field set. Check fc-scan --help on older systems before using this option in a portable script; the local older manpage does not mention it at all.
Fontconfig 2.15.0 includes -y and --sysroot. It prepends a root to paths for scanning, handy when examining a mounted or staged filesystem, but it does not turn an arbitrary host directory into a valid target:
$ fc-scan --sysroot=/mnt/staged-root /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
Before running that, replace /mnt/staged-root with a directory that actually contains the requested path, and check it without elevation:
$ test -r /mnt/staged-root/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf && echo readable
readable
--sysroot is not the same thing as changing the host's font directories. It affects only this scan invocation. A wrong root usually leads to an empty result or an error, not a scan of the host file you meant to avoid.
Check the input path and permissions first.
$ ls -ld /path/to/font-or-directory
$ test -r /path/to/font-or-directory && echo readable
Then verify the status right after the command. The local manpage says the return code is 0 if at least one font was found and 1 otherwise:
$ fc-scan /tmp/definitely-no-such-font >/tmp/fc-scan-output
$ status=$?
$ printf 'fc-scan status: %s\n' "$status"
fc-scan status: 1
Status 1 under that documented contract means the scan found no font. It can mean a wrong path, unreadable input, a non-font file, or a font excluded by Fontconfig's own scanning rules. Read the path and diagnostics before touching configuration. If a directory scan unexpectedly skips a file, test that file directly and check its permissions and format.
For scripts, keep machine-readable output separate from diagnostics. Redirecting standard output to a report is fine, but never parse the full pattern as if field order were an API. Prefer a small explicit --format template, and record the Fontconfig version alongside the report.
fc-scan --version identified it and the Fontconfig version.--format string was used instead of relying on verbose field order.