13

I used the following command to check python versions as given by this answer. It does work except for one error, shown below. Can any one explain why?

$ sudo find / -type f -executable -iname 'python*' -exec file -i '{}' \; \
    | awk -F: '/x-executable; charset=binary/ {print $1}' \
    | xargs readlink -f | sort -u | xargs -I % sh -c 'echo -n "%: "; % -V'

Error:

find: ‘/run/user/1000/gvfs’: Permission denied
  • 2
    python --version and python3 --version to show the active version. We all have a 2.x version and the a 3.x version ;) – Rinzwind Oct 20 '16 at 08:18
  • 6
    And the error is normal and not a problem with the command. /run/ should not be included in "find". gvfs is not owned by your user. – Rinzwind Oct 20 '16 at 08:20
  • 1
    You can also type python in the console and press the tab key twice, it'll show every executable in your path starting with python. – Timo Oct 20 '16 at 08:21
  • dpkg -l | grep python. – fkraiem Oct 20 '16 at 08:28
  • 7
    Good grief, people. I'm making a fairly hefty edit to the question because some people didn't manage to make it to the first paragraph. The OP knows how to find which versions, the question is about why this command (which finds all versions of Python) is chucking out a specific error. If you want to post about python -V and alternatives, please take it to to a question actually soliciting that information. – Oli Oct 20 '16 at 10:22
  • 1
    Running the command in the the question is a bad idea, it will find any file on your system whose name starts with python and execute it as root. If your users find out you use this command then you just handed them a trivial root-exploit. – Peter Green Oct 20 '16 at 12:42
  • 1
    @PeterGreen That is false; the command will invoke the file utility on every executable it finds. It doesn't execute them. See the -exec file -i '{}' \;. – marcelm Oct 20 '16 at 13:23
  • @marcelm you may need to change it to -exec file -i -- '{}' \; to fix a problem with filenames starting with -. – Demi Oct 21 '16 at 03:58
  • 1
    @PeterGreen there is an obvious shell injection (the argument to xargs injects user-controlled filenames into a shell command, since filenames can contain colons) – Demi Oct 21 '16 at 04:06

2 Answers2

20

The permissions:

$ stat -c %a /run/user/1000/gvfs
500

So only the owner has execute permission (which allows directories to be searched). But, you used sudo and root has all possible permissions, right? Actually you found the exception:

This answer by Gilles on Unix and Linux SE explains why permission is denied for root that directory, which is a mountpoint for FUSE:

Managing trust boundaries with FUSE filesystems is difficult, because the filesystem driver is running as an unprivileged user, as opposed to kernel code for traditional filesystems. To avoid complications, by default, FUSE filesystems are only accessible to the user running the driver process. Even root doesn't get to bypass this restriction.

If you run the find command without sudo (as your own user, UID 1000) you will not get that error, because you own the directory, but you will get other permission errors instead, so, use sudo and take Gilles' advice:

If you're searching for a file on local filesystems only, pass -xdev to find.


Easiest way to check python versions:

$ python --version
Python 2.7.12+
$ python3 --version
Python 3.5.2+
Zanna
  • 70,465
  • I have only one user except root then who do you expect to own it? – abdul qayyum Oct 20 '16 at 09:00
  • 1
    It's you, UID 1000. You can cd to that directory as your normal user, but not as root. If you run find without sudo you will not see that error (but you will get other permission errors of course) – Zanna Oct 20 '16 at 09:03
  • 2
    @abdulqayyum Are you sure? By default ubuntu has quite a few users associated with various daemon processes. So yes, they can't login and they don't have a home directory but they exist and can own files and directories... – Bakuriu Oct 20 '16 at 12:16
7

There is several ways to find what version of python you have. Here are two ways you'll get both Python 2 and Python 3 versions:

Python Specific

First just run python and python3 with the option --version

$ python --version
Python 2.7.12
$ python3 --version
Python 3.5.2

This is specific for python, but a lot of other programs use a similar method.

General for any package/program

A more general method is to see what package is installed. dpkg -l will list out all your packages, but you can specify what packages you are looking for. For just python and python3 use the following:

$ 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  python                2.7.11-1        amd64           interactive high-level object-oriented language 
$ dpkg -l 'python3'
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  python3               3.5.1-3         amd64           interactive high-level object-oriented language 

As an extra titbit. If you'd like to find all the packages that has a name starting with python, you can use wildcard character * like this:

$ dpkg -l 'python*'

That will print a lot of lines with packages.

Jorgen
  • 558