Track Debian Releases from Scripts with debian-distro-info
Hard-code a codename like trixie into a script and it is wrong the day Debian promotes the next release; debian-distro-info fixes that. The examples use package distro-info 1.7build1, with the local debian-distro-info(1) manual as reference.
The route
Jump straight to the step you need, or tick off Done means at the end.
- Allow: about ten minutes.
- You need: a shell and the
distro-infopackage. - Privilege: everything here is read-only and runs as your normal user. No
sudo, service restart, or repository change involved.
1. Check the installed command
Confirm which executable will actually run and which package supplied it:
$ command -v debian-distro-info
/usr/bin/debian-distro-info
$ dpkg-query -W -f='${Package} ${Version}\n' distro-info
distro-info 1.7build1
Then read the installed help:
$ debian-distro-info --help
Usage: debian-distro-info [options]
The manual page installed here is older than the command. Its core options still hold, but this build also advertises --oldstable, --lts, --elts, and the eol-lts and eol-elts milestones. Writing a script for this package version, check --help on the target system before leaning on those newer options.
2. Ask for the current release role
One selector at a time gets you a particular moving release:
$ debian-distro-info --stable
trixie
$ debian-distro-info --testing
forky
$ debian-distro-info --oldstable
bookworm
$ debian-distro-info --devel
sid
These return the codename by default, and the result changes as Debian promotes releases, so capture it in a variable rather than treating trixie or forky as fixed facts:
$ stable=$(debian-distro-info --stable)
$ printf 'stable codename: %s\n' "$stable"
stable codename: trixie
Checkpoint
A script needing a codename should now be using this command's result. Needing a release number or display name instead means choosing the output format explicitly, which is the next step.
3. Choose the output format
--codename is the default. Add --release for the numeric release, or --fullname for Debian's display name:
$ debian-distro-info --stable --codename
trixie
$ debian-distro-info --stable --release
13
$ debian-distro-info --stable --fullname
Debian 13 "Trixie"
Long options are easier to audit in a deployment script than short forms, and should be preferred anywhere you do not fully control the surrounding command:
$ debian-distro-info --stable --release
13
$ debian-distro-info --stable --fullname
Debian 13 "Trixie"
Do not parse the full name to dig the number back out. Ask for --release directly, which keeps a script independent of punctuation and capitalisation in human-readable output.
4. Inspect every known or supported series
Use --all for the complete data set, old releases and development series included. Add an output selector when a list of release numbers is more useful than codenames:
$ debian-distro-info --all --release
1.1
1.2
...
13
14
sid
experimental
The ellipsis above is explanatory only, not literal command output. For a shorter operational list, use --supported, which on this installation returns stable, testing, and development entries:
$ debian-distro-info --supported
trixie
forky
sid
experimental
--unsupported lists unsupported stable releases. None of this upgrades, removes, or enables anything: it only reads the distro-info data shipped with the package.
5. Reproduce the answer for a historical date
Release roles move over time, so pass an ISO date with --date=YYYY-MM-DD when testing an old deployment decision or a dated build:
$ debian-distro-info --date=2024-01-01 --stable --codename
bookworm
$ debian-distro-info --date=2024-01-01 --stable --release
12
Without --date, the command uses today. The manual also documents SOURCE_DATE_EPOCH as the default epoch when it is set; verify the behaviour on the target package if a reproducible build depends on it:
$ SOURCE_DATE_EPOCH=1704067200 debian-distro-info --stable --release
12
An invalid date fails outright instead of quietly picking a release:
$ debian-distro-info --date=not-a-date --stable
debian-distro-info: invalid date `not-a-date'
6. Convert a codename to its current alias
--alias=DIST answers a different question entirely: which role does a given codename hold right now?
$ debian-distro-info --alias=bookworm
oldstable
$ debian-distro-info --alias=trixie
stable
$ debian-distro-info --alias=forky
testing
$ debian-distro-info --alias=sid
unstable
Only lower-case ASCII codenames are accepted. An otherwise valid but unknown lower-case codename comes back unchanged:
$ debian-distro-info --alias=notarelease
notarelease
$ debian-distro-info --alias=Bad-Name
debian-distro-info: invalid distribution codename `Bad-Name'
An unchanged result is not proof the name is a real Debian series. If that matters, cross-check it against --all or treat an unknown name as an application-level error.
7. Add release dates or end-of-life estimates
--days appends or returns the number of days to a milestone. The local manual documents created, release, and eol; this installed command additionally accepts eol-lts and eol-elts:
$ debian-distro-info --days=release --stable
-410
$ debian-distro-info --days=eol --stable
686
A negative number means the milestone has already passed relative to the calculation date. Combine --days with a list option and you get the normal value plus a day count together, so use a single selector when you need a clean, machine-readable scalar. Dates and support data can shift as package data updates, so do not treat the number as a maintenance guarantee.
8. Keep scripts predictable
Prefer explicit selectors and output formats, quote shell variables, and check the exit status before using a result:
$ series=$(debian-distro-info --stable --codename) || exit 1
$ release=$(debian-distro-info --stable --release) || exit 1
$ printf 'Debian %s (%s)\n' "$release" "$series"
Debian 13 (trixie)
This is not an upgrade mechanism, and a release being labelled stable is not by itself a reason to consider it safe to deploy. It reports distro-info's data; package compatibility, security support, and your own change controls remain separate checks. There is no recovery step to worry about, since every example here only queries local metadata.
Done means
- Confirmed the executable and installed
distro-infoversion. - Retrieved stable, testing, oldstable, and development codenames without hard-coding them.
- Selected codename, release number, or full name explicitly.
- Reproduced a role for a historical date and can recognise invalid input.
- Treated aliases and support-day counts as changing package data, not an upgrade plan.
- Made no privileged or persistent system changes.