Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
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 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 at 13:06
    
Won't work on all systems, but a few more solutions from askubuntu – BroSlow Mar 1 at 0:23
up vote 8 down vote accepted

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)
share|improve this answer
    
This will miss if there's 2.xx or 3.xx – cuonglm Feb 29 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? – Faheem Mitha Feb 29 at 16:40
    
Of course, there're anything like that yet. – cuonglm Feb 29 at 16:48

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.

share|improve this answer
    
is this like (bash) locate g++ python | xargs | readlink - (or thereabouts)? – cat Feb 29 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? – Faheem Mitha Feb 29 at 16:08

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

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

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
share|improve this answer
    
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. – Faheem Mitha Feb 29 at 13:34
    
@FaheemMitha: It's not regular expression but glob pattern. – cuonglm Feb 29 at 13:51
    
This is nice, but what about binaries that weren't installed by package manager? – Xarn Feb 29 at 13:58
    
@Xarn: You need to do it by hand, this approach can not handle that situation. – cuonglm Feb 29 at 14:00
    
@cuonglm True, glob pattern, not regular expression. – Faheem Mitha Feb 29 at 15:01

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++
share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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