2

So as the question suggests, I want to get the version of a command inside a bash script, instead of using the terminal.

I know that all available commands are present as files inside the directory /usr/bin. But it does not give the versions and it gives some funny information when you use cat for one of the (command) files.

for example - cat /usr/bin/man gives -

funny output

What is this and how do I get the version?

I am using Ubuntu 20.04.

I know its a stupid question to ask here but I wasn't able to find anything :/

Supposedly the final edit - the accepted answer works for me, I am using the function.

I did also realise later that something like foo --version will work too

But, if you are using a variable to store the version then you need to be careful about the syntax, I was doing it the wrong way. Thanks to @Romeo Ninov for pointing out that
foo --version works too.

I am really sorry for these silly mistakes.

9
  • Regarding your recent update: Which answers can't be used in a script?
    – Kusalananda
    Jul 8, 2022 at 8:54
  • i wouldn't say that they can't be used inside a script, I just don't know how to do it. Jul 8, 2022 at 9:05
  • 3
    Formal note: the answer you accepted is not the first one chronologically. If you mean "the first answer from the top" then please note each user can choose a sorting method independently. Therefore the term "first answer" is not well-defined, in general it can easily confuse users who see different order of answers. For future reference: if you really need to address an answer anywhere else than in comments under the very answer, link to it. In this case we know what answer you probably mean: the accepted one. Jul 8, 2022 at 11:58
  • 1
    The main difference between an interactive shell session and a script is where it reads commands from (a terminal for the former, a file for the latter).
    – chepner
    Jul 8, 2022 at 15:45
  • 1
    Please don't post images of text. They can be hard to read, impossible to search/index, and cannot be pasted into terminals to test.
    – doneal24
    Jul 8, 2022 at 17:50

3 Answers 3

7

If you are on a Debian based distribution, you can use the package manager to figure it out:

$ dpkg -S '*bin/man'
man-db: /usr/bin/man

This tells us man-db is the package which owns /usr/bin/man.

$ dpkg -l man-db
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=================================
ii  man-db         2.10.2-1     amd64        tools for reading manual pages

Then we ask what version of man-db is installed. This is man-db's upstream version 2.10.2 released by the distribution with an extra -1. The -1 represents a patch done by the distribution. This may just include build-rules, but could also include fixes to 2.10.2 ported from later versions.

dpkg-query can be used to extract the version:

$ dpkg-query -W -f '${Version}\n' man-db
2.10.2-1

Putting all this together:

$ dpkg-query -W -f '${Version}\n' $(dpkg -S '*bin/man' | cut -d: -f1)
2.10.2-1

Or a function which could go into .bashrc:

ver() {
  package=$(dpkg -S "*bin/$1" | cut -d: -f1)
  version=$(dpkg-query -W -f '${Version}' "$package")
  printf "%s\n" "$version"
}

ver man
2.10.2-1

(Behind the scenes, dpkg -S is really dpkg-query -S, but dpkg-query -S can't be combined with -W -f.)

1
  • Lol I was confused when I first looked at the answer, but it worked. Thanks a lot :) Jul 8, 2022 at 9:20
5

AFAIK there is no firm single way to get the version from an arbitrary command foo (by running it or by analyzing the executable). Some foos may tell you something upon foo -v, others upon foo -V or foo --version, foo --help, foo -h, …; it's totally up to them (i.e. their authors).

Read the manual (man foo) to find out which of these options (if any, or yet another) the tool supports. The manual itself may tell you the version (usually at or near the bottom), but in this case it's the version of foo the manual describes, not necessarily the version of foo you can use. In a system where tools and their manuals are installed from repositories, these should correspond; but in general it's possible to get and use foo in a different version (or versions) than the manual describes.

The package system used by your distribution may provide you a firm way to see the versions of installed packages (examples for Debian and derivatives, including Ubuntu). If you know which package the tool you're after belongs to (again, for Debian and…), you can often deduce the version of the tool from the version of the package.

In general an executable may or may not be in a binary format; it may be a script for an arbitrary interpreter. There is no requirement for it to include its version anywhere in the file or to report in its output. In some cases the whole concept of versions does not apply. E.g. my script from this other answer has no version assigned to it. Similarly this wrapper I analyzed in yet another answer has no version (it came with a package that has a version though).

The conclusion is you cannot reliably get the version of an arbitrary executable from the executable itself; unless it's a particular executable and you tune your script to it (i.e. parse foo -V or whatever is right for this particular executable). You can get the version of a package.

I can see this concurrently written answer has provided a way to get the version of the package that owns a given executable. I won't reinvent it then.

3
  • I am trying to get the version inside a shell script instead of the terminal. For the terminal I guess it could be managed but I don't know for the shell script Jul 8, 2022 at 8:56
  • 1
    @AntasSharma I gave you no shell code because this other answer beat me to it and I couldn't do significantly better. The code there is exactly for a shell like Bash, interactive or not; the ver function even sets shell variables you can use later without additional effort. Jul 8, 2022 at 9:06
  • Ah I realised later that it works in a shell script. Thanks Jul 8, 2022 at 9:21
1

The usual way to get version of command is to use command like:

man --version

Be warned this can give you more than one line as answer so you should manage this. Also for each command you can check man page. For example:

man man

where you can see eventually the version. If you want to get it directly from the binary file you can try with

strings /usr/bin/man

and filter the result

3
  • 1
    Ah I've used the v flag but I don't know how to make it work inside a shell script. Jul 8, 2022 at 8:57
  • 1
    @AntasSharma Why would it be any different inside a shell script? Programs can't generally tell the difference between running from the CLI and running from a script and they don't behave differently.
    – Barmar
    Jul 8, 2022 at 13:58
  • 1
    Oh my god, it wasn't working for me because I was using a variable to store the variable and I didn't know the exact syntax for that. I made a file with just the command man --version and it worked. Jul 8, 2022 at 17:32

You must log in to answer this question.

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