3

Due to bureaucracy, I am in a situation where I can get someone to run a bash script on a Linux server and give me outputs, but I cannot log in there, or run the script myself.

I am fairly certain that the server in question is running Debian or Ubuntu.

I want to find out which python and which g++ versions are installed (long story).

So far my best idea is to get $PATH variable, split it by :, and then search all the paths for everything matching python, g++ respectively.

Is there a saner way?

3
  • 1
    Is there a possibility that there are compilers/interpreters not installed by the package manager? If that's not the case simply use dpkg
    – schaiba
    Feb 29, 2016 at 12:44
  • @schaiba There is, especially since I am looking for sufficiently modern version in case of g++. (It has to support C++14)
    – Xarn
    Feb 29, 2016 at 13:06
  • Won't work on all systems, but a few more solutions from askubuntu
    – user60101
    Mar 1, 2016 at 0:23

6 Answers 6

9

The following should work for g++, provided that you have no local g++ installations.

dpkg -l 'g++*'

On my system, this gives:

dpkg -l 'g++*'
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  g++                              4:4.9.2-2             amd64                 GNU C++ compiler
ii  g++-4.6                          4.6.3-14              amd64                 GNU C++ compiler
un  g++-4.6-multilib                 <none>                <none>                (no description available)
ii  g++-4.9                          4.9.2-10              amd64                 GNU C++ compiler
ii  g++-4.9-multilib                 4.9.2-10              amd64                 GNU C++ compiler (multilib files)
ii  g++-multilib                     4:4.9.2-2             amd64                 GNU C++ compiler (multilib files)

For Python, a similar approach will pick up too many false positives, because on Debian and its derivatives, all Python libraries start with python-. So, one would need a more refined glob pattern.

Something like

dpkg -l 'python?.?'

should work.

dpkg -l 'python?.?'
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  python2.6                        2.6.8-1.1             amd64                 Interactive high-level object-oriented language (version 2.6)
ii  python2.7                        2.7.9-2               amd64                 Interactive high-level object-oriented language (version 2.7)
un  python3.1                        <none>                <none>                (no description available)
ii  python3.4                        3.4.2-1               amd64                 Interactive high-level object-oriented language (version 3.4)
3
  • This will miss if there's 2.xx or 3.xx
    – cuonglm
    Feb 29, 2016 at 16:31
  • @cuonglm True. One should come up with a more flexible version. Though has there ever been a Python 2.xx or 3.xx in Debian? Feb 29, 2016 at 16:40
  • Of course, there're anything like that yet.
    – cuonglm
    Feb 29, 2016 at 16:48
4

With zsh:

$ type -ma '(python|g++)*'
g++ is /usr/bin/g++
g++-4.4 is /usr/bin/g++-4.4
g++-4.6 is /usr/bin/g++-4.6
g++-5 is /usr/bin/g++-5
python is /usr/bin/python
python-config is /usr/bin/python-config
python-coverage is /usr/bin/python-coverage
python2 is /usr/bin/python2
python2-config is /usr/bin/python2-config
python2-coverage is /usr/bin/python2-coverage
python2-gflags2man is /usr/bin/python2-gflags2man
python2.7 is /usr/bin/python2.7
python2.7-config is /usr/bin/python2.7-config
python2.7-coverage is /usr/bin/python2.7-coverage
python3 is /usr/bin/python3
python3.2 is /usr/bin/python3.2
python3.2mu is /usr/bin/python3.2mu
python3.4 is /usr/bin/python3.4
python3.4m is /usr/bin/python3.4m
python3.5 is /usr/bin/python3.5
python3.5m is /usr/bin/python3.5m
python3m is /usr/bin/python3m
pythontex is /usr/bin/pythontex
pythontex3 is /usr/bin/pythontex3

Like type cmd but reports all the commands (and aliases and functions and builtins which would be relevant if the shell of the user happens to be zsh) that match the pattern.

2
  • is this like (bash) locate g++ python | xargs | readlink - (or thereabouts)?
    – cat
    Feb 29, 2016 at 16:08
  • 1
    This looks impressively efficient, but it's picking up stuff that's not installed. Could you explain what this command does, please? Feb 29, 2016 at 16:08
4

If you want the versions that are in $PATH, you can run:
python -V ; g++ --version

4
  • 2
    The second version here really doesn't serve any purpose.
    – jordanm
    Feb 29, 2016 at 14:38
  • Indeed... Edited
    – csny
    Feb 29, 2016 at 17:20
  • 1
    I am a little bit surprised, how could everybody miss this...
    – peterh
    Feb 29, 2016 at 21:28
  • @peterh This will only print the first versions in your path
    – user60101
    Mar 1, 2016 at 0:21
3

Just Using the OS package manager to query:

$ dpkg -l | awk '/^ii/ && $2 ~ /^python[0-9](\.[0-9]+)+$/ {print $2}'
python2.6
python2.7
python3.2
python3.4
5
  • The poster also asked about g++. If one is going to query dpkg, it certainly supports regular expressions, so that would be the way to go, imo. Feb 29, 2016 at 13:34
  • @FaheemMitha: It's not regular expression but glob pattern.
    – cuonglm
    Feb 29, 2016 at 13:51
  • This is nice, but what about binaries that weren't installed by package manager?
    – Xarn
    Feb 29, 2016 at 13:58
  • @Xarn: You need to do it by hand, this approach can not handle that situation.
    – cuonglm
    Feb 29, 2016 at 14:00
  • @cuonglm True, glob pattern, not regular expression. Feb 29, 2016 at 15:01
0

You can use which -a to search the path.

function get_versions {
    for p in $(which -a $1); do
        $p --version
    done
}

get_versions python
get_versions g++
0

Given that you don't know everything about the system that your script will run on and you won't have an easy time fixing it, you should keep it low-tech and low-assumption.

Write a portable sh script that enumerates PATH. That takes care of non-package installations as well as package installation, as long as the non-package installations are in an advertised place. (If you can't trust the administrators to have made the installations you want discoverable, you're better off installing your own.)

#!/bin/sh
set -f; IFS=:
set -- $PATH
set +f; unset IFS
for dir; do
  if [ -x "$dir/python" ]; then printf %s "$dir/python is "; "$dir/python -V; fi
  ls -l "$dir/python"* 2>/dev/null
  if [ -x "$dir/python" ]; then printf %s "$dir/g++ is "; "$dir/g++ --version | head -n 1; fi
  ls -l "$dir/g++"* 2>/dev/null
done

The output of this script is just a sample, you may want to make it easier to parse.

You must log in to answer this question.

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