44
$ 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

52

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,. ]/ } ?
    – terdon
    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.
    – terdon
    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.
    – terdon
    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
7

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.
    – terdon
    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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .