42
$ lsb_release -c
Codename:   trusty

$ cat /etc/issue
Ubuntu 14.04 LTS \n \l

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04 LTS"

Output's of the above commands shows only the partial code name (ie, trusty). How do I get the full codename (trusty tahr) of my installed Ubuntu system?

1
  • 2
    It seems that there's a convergent process towards the sourcing of the file /etc/os-release. Maybe you should specify what you mean by How do I get the full codename(trusty tahr) of my installed Ubuntu system?. Do you only want to echo it on the terminal, or do you need it assigned to a variable? Is this going to be used on some non-{Ubuntu,Debian} systems? Apr 19, 2014 at 11:42

9 Answers 9

50

Using no external tools:

You can just source (the source command is a dot .) the /etc/os-release and you'll have access to all the variables defined there:

$ . /etc/os-release
$ echo "$VERSION"
14.04, Trusty Tahr

Edit. If you want to remove the 14.04, part (as asked by terdon), you could:

$ . /etc/os-release
$ read _ UBUNTU_VERSION_NAME <<< "$VERSION"
$ echo "$UBUNTU_VERSION_NAME"
Trusty Tahr

Note that this is a bit clunky, since on other distributions, the VERSION field can have different format. E.g., on my debian,

$ . /etc/os-release
$ read _ UBUNTU_VERSION_NAME <<< "$VERSION"
$ echo "$UBUNTU_VERSION_NAME"
(wheezy)

Then, you could imagine something like this (in a script):

#!/bin/bash

if [[ -r /etc/os-release ]]; then
    . /etc/os-release
    if [[ $ID = ubuntu ]]; then
        read _ UBUNTU_VERSION_NAME <<< "$VERSION"
        echo "Running Ubuntu $UBUNTU_VERSION_NAME"
    else
        echo "Not running an Ubuntu distribution. ID=$ID, VERSION=$VERSION"
    fi
else
    echo "Not running a distribution with /etc/os-release available"
fi
5
  • 1
    (echo is builtin) but OK, how about this: . /etc/os-release && echo ${VERSION//[0-9,. ]/ } ? Apr 19, 2014 at 11:07
  • 1
    @terdon there's more than one way to skin a cat ;D. Apr 19, 2014 at 11:15
  • What happened to all the comments here? Apr 19, 2014 at 11:17
  • 2
    There are many and yours is a particularly good one! Comments that are irrelevant to the actual answer can be deleted without warning. Apr 19, 2014 at 11:17
  • the embedded variable and value in os-release currently is defined to something like this: VERSION="18.04.2 LTS (Bionic Beaver)" Feb 6, 2020 at 10:42
10

My variant on what's already offered:

. /etc/os-release; echo ${VERSION/*, /}

The shortest, Bashiest answer to date.

If you don't care to load /etc/os-release's contents into your current environment, you can fake bash into thinking it's loading a script fairly easily:

bash <(cat /etc/os-release; echo 'echo ${VERSION/*, /}')
6
  • 3
    How dare you say bashier than anything else to date? there are other full bash answers here :D. Apr 19, 2014 at 11:19
  • 1
    Why the downvote? it's a good answer (though with nothing conceptually different from others given before it). Apr 19, 2014 at 11:21
  • 3
    Heh, clever use of process substitution, +1. Apr 19, 2014 at 11:29
  • 1
    as one would expect from the master @terdon :)
    – Rinzwind
    Apr 19, 2014 at 11:29
  • 2
    A simple subshell would do the job as well: ( . /etc/os-release && echo ${VERSION/*, /} ). Apr 19, 2014 at 11:37
8

Grep:

$ grep $(lsb_release -rs) /usr/share/python-apt/templates/Ubuntu.info | grep -m 1 "Description: Ubuntu " | cut -d "'" -f2
Trusty Tahr

Explanation:

  • lsb_release -rs -> Prints your installed Ubuntu version.

  • grep $(lsb_release -rs) /usr/share/python-apt/templates/Ubuntu.info -> Grab all the lines which contains your release version, in my case it's 14.04.

  • grep -m 1 "Description: Ubuntu " -> Again grabs only the matched first line(because of -m flag) which contains the string Description: Ubuntu.

  • cut -d "'" -f2 -> prints the field number 2 according to the delimiter single quote '

Awk:

$ awk -v var=$(lsb_release -rs) '$3~var {print $4" "$5;exit;}' /usr/share/python-apt/templates/Ubuntu.info | cut -d"'" -f2
Trusty Tahr

Explanation:

Declaring and assigning Variable in awk is done through -v parameter.So the value of lsb_release -rs command is assigned to the variable var which inturn helps to print field 4 ,field 5 from the lines contain the string 14.04 and exists if its found an one.Finally the cut command helps to remove the single quotes.

3
  • it seems your solutions are based upon some python module for apt. that would mean a dependency on the file location and also on its formatting. also it only works if lsb_release with those options does provide a string that will match for the initial search operation. - nevertheless pointing out to those second source(!) to let others know about can in some special case be worth a million. Feb 6, 2020 at 10:55
  • the grep variant might be able to be coded even shorter (with maybe a slight deviation on the exact search term - might not have practical relevance) - try this one: grep -m 1 "Description: Ubuntu lsb_release -rs" /usr/share/python-apt/templates/Ubuntu.info | cut -d \' -f 2 Feb 6, 2020 at 12:39
  • oops, left-ticked quotes vanished as mini-Markdown syntax understood these as code highlighting request. you will have to undo this for the proposal to work. Feb 6, 2020 at 12:53
6

Answer relevant for at least ubuntu 16.04 and above:

lsb_release -cs

If for some reason lsb_release is not available

cat /etc/os-release | grep UBUNTU_CODENAME | cut -d = -f 2
1
  • even if i see some sympathy to your second way of parsing (instead of sourcing) the file in question - neither of the two options returns the full code name - only the first half is retrieved. xenial instead of xenial xerus, bionic instead of bionic beaver. sorry - that was not the question here. Feb 6, 2020 at 10:51
4

The command you are looking for is:

grep -oP '(?<=VERSION\=\"(\d\d)\.(\d\d)\,\ )(.*?)(?="$)' /etc/os-release

This is very ugly and not optimized. I'm sure there should be an easier method and this has some issues.

0
2

Here are some more choices. They all parse the /etc/os-release file which, on my 13.10, looks like this:

NAME="Ubuntu"
VERSION="13.10, Saucy Salamander"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 13.10"
VERSION_ID="13.10"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

All of the solutions below will parse the second line to produce Saucy Salamander.

  1. grep

    grep -oP 'VERSION=.* \K\w* \w*' /etc/os-release
    

    The -o means "print only the matching part of the line" and the -P enables Perl Compatible Regular Expressions. This lets us use \K which discards whatever was matched up to that point, which combined with -o means "print only what matches after the \K. So, the actual regular expression used will match the last two words of a line that contains VERSION=.

  2. awk

    awk -F'[" ]' '/VERSION=/{print $3,$4}'  /etc/os-release
    

    Setting the fields separator to " and space means that the 3d and 4rth fields of the line containing VERSION= are the string we're after.

  3. sed

    sed -nr '/VERSION=/{s/.* (\w* \w*)"/\1/;p}' /etc/os-release
    

    The -n switch suppresses normal output, no lines will be printed. The -r allows extended regular expressions. Then, on lines that match VERSION=, we will delete everything except the last two words. The p at the end means print.

  4. perl

    perl -lne '/VERSION=.*\b(\w+ \w+)/ && print $1' /etc/os-release
    

    The -n means 'process every input line with the script given by -e". The -l adds a newline character to every print call (and some other stuff which is not relevevant here). The regular expression matches the last two words (\b is a word boundary) and prints them if the line contains VERSION=.

  5. coreutils

    grep VERSION= /etc/os-release | cut -d ' ' -f 2-  | tr -d '"' 
    

    Here, we just grep the relevant line and use cut setting the field separator to space (-d ' ') and printing everything from the 2nd field to the end of the line. The tr -d command will delete the " from the end.

  6. Pure shell (shamelessly stealing @gniourf_gniourf's clever source idea):

    . /etc/os-release && echo ${VERSION//[0-9,. ]/ }
    

    The . sources the file which makes the variables available to the shell and I use bash's string manipulation capabilities to remove the version numbers.

1
. /etc/os-release 
echo $VERSION
1
  • 3
    You still need to remove the numbers, see @gniourf_gniourf's answer below that uses exactly the same approach. Apr 19, 2014 at 11:18
1

Using regex you could do this:

grep 'VERSION' /etc/os-release | grep -oP "[a-zA-Z]+ [a-zA-Z]+"

Explanation:

This searches the line with VERSION in the file /etc/os-release. Then it finds 2 successive words seperated by a space (Perl regex). The -o flag keeps only what matches the search.

You have to use [a-zA-Z] instead of `w` to avoid including digits.

0

I favor the delimiter-splitting awk variant:

awk -F "[()]" '/VERSION=/ {print $2}' /etc/os-release

The distro itself is retrievable via /usr/bin/lsb_release -sd.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.