23

Need to verify whether it is installed or not before the program can run.

2
  • 2
    Just run the pip install. If it's already installed, it won't install it again.
    – jordanm
    Commented Oct 10, 2015 at 17:34
  • Thnk you jordanm, but i need to check and give a o/p then testing.
    – hubatrix
    Commented Oct 10, 2015 at 17:38

10 Answers 10

22

You should use pip's list command with grep, that only lists installed packages (not all modules and their neighbours as well):

pip list | grep -F package_name

If package_name matches multiple installed packages e.g. searching for boto when botocore is also installed, then using -w instead of -F can help, as @TaraPrasadGurung suggests. This doesn't list the exact package, as -w sees characters common in package names as word boundaries. So if you you have requests and requests-cache installed or ruamel.yaml and ruamel.yaml.cmd` and need exactly one line of output you need to do something like:

pip list --disable-pip-version-check | grep -E "^ruamel\.yaml "

Please note that since . matches any character when using -E, you need to escape it.¹


¹ And yes that is necessary as there is a package ruamel_yaml. Not every package manager is pip compatible when dealing with namespace packages.

4
  • The problem with this is if the package name boto and botocore is installed it will list both of them. So the better solution will be to use -w flag instead of -F to list the exact package Commented Feb 24, 2019 at 6:58
  • @TaraPrasadGurung Although that can help reduce the output somewhat it doesn't help to get the exact package as you claim. E.g. the dot and dash are taken by -w as word boundaries and are common in package names. I get multiple matches when I use your suggestion using grep -w ruamel.yaml or grep -w request
    – Anthon
    Commented Feb 24, 2019 at 7:29
  • pip list | grep -F mxnet-cu101 prints mxnet-cu101 1.5.0, but not exactly where it is installed. any idea how to get the installed path? `
    – Anu
    Commented Jul 26, 2019 at 3:03
  • @any Yes, I have a good idea on how to retrieve where a Python package is installed given I know its name. You should post a question on this site and ping me here for my attention when you do, as I don't follow newly posted questions on U&L.
    – Anthon
    Commented Jul 26, 2019 at 6:49
8

If the package doesn't do something crazy or time consuming on import you can try actually importing it:

if python -c "import package_name" &> /dev/null; then
    echo 'all good'
else
    echo 'uh oh'
fi
8

Tested with pip3:

$> pip3 show MODULENAME

The exit-code ($?) would be "0" in case the module is installed, else "1".

Grepping has the problem of "false positives": The output of a

pip list | grep NAME

would match on any module which name contains "NAME", e.g. also match "some_other_NAME".

While

pip3 show MODULENAME

only matches on complete matches.

2
  • wow this needs more upvotes. Trying to cobble something together with grep is definitely not worth the trouble. Neither is installing pkg_util if you don't already need it.
    – Brian
    Commented Mar 23, 2021 at 15:12
  • @Brian I agree. While it's interesting to go through the other answers and see the logic, it's extra nice that "show" works so well. The one caveat is that it doesn't show native modules e.g. os. (I may be overlooking something here, for instance that it can't really give version information.)
    – aschultz
    Commented May 28, 2021 at 0:56
7

Type in the shell: pydoc modules .
This will list modules and you can grep the module which you want.
Found on stackoverflow here

5

I have found existing answers incomplete and lacking good enough examples. Here is the solution I have settled on:

# an example checking if the pandas package is installed
if python -c 'import pkgutil; exit(not pkgutil.find_loader("pandas"))'; then
    echo 'pandas found'
else
    echo 'pandas not found'
fi

A Github gist of this example can be found here: https://gist.github.com/shaypal5/d505af9953cd86f59c750fa600ee4ba6

2
  • this looks really similar to an existing answer
    – Jeff Schaller
    Commented Jul 21, 2018 at 17:13
  • 1
    The bash code is similar, the Python code is different, which makes quite a difference. I have read all existing answers before choosing to add my own, and the specific answer you linked to did not work for me. Thus, I find it relevant and valuable to add my answer here. :) Commented Jul 22, 2018 at 8:18
1

You can also use something like this in your scripts.

python -c "import sys, pkgutil; sys.exit(0 if pkgutil.find_loader('$Package') else 1)"

What you'd get when a package is not installed.

Package=psutil
python3 -c "import sys, pkgutil; sys.exit(0 if pkgutil.find_loader('$Package') else 1)"
echo $?
1

What you'd get when a package is installed.

Package=requests
python3 -c "import sys, pkgutil; sys.exit(0 if pkgutil.find_loader('$Package') else 1)"
echo $?
0

Works in python2 and python3, and then you install based on the exit code.

1

To expand on Thomas Hofmann's answer, because pip3 show does return a nonzero exit code for packages which aren't installed, you can accomplish what you want with:

if pip3 show package_in_question &> /dev/null; then
    run_program
fi
0

I used a slightly stricter version of Anthon's answer, for use in a script:

pip3 list |
    grep -v "^Package *Version$" | grep -v "^-*$" |
    cut -d ' ' -f 1 |
    grep -xF "$package_name"

The first two greps are intended to strip the header lines from pip3's output.

The cut then selects only the package names (discarding the version numbers).

Then the final grep can perform an exact search for the relevant $package_name

If the package is found, it will display the package name, and return with exit code 0. If you don't want to see the package name, end the command with >/dev/null

0

in a Python shell/prompt. :

>>> help('modules')
0

I needed this inside my bash script so I ended up by using:

CHECK1=$(<package_name> --version)
CHECK1=$(echo $CHECK1 | awk '{print $1}')
# or: 
CHECK1=$(pip freeze | grep <package_name>)
CHECK1=$(echo $CHECK1 | awk '{print $1}' | awk -F '==' '{print $1}')

For example:

# Check if the virtualenv exists. 
CHECK1=$(virtualenv --version)
CHECK1=$(echo $CHECK1 | awk '{print $1}')

After that, I can use the $CHECK1 in if statement to automate other stuff.

if [[ $CHECK1 = 'virtualenv' ]] 
then 
   echo "Yes virtualenv library exists"
else
   echo "No it does not exist... " 
   #.... you can later ask the user to install it or not...

Presumably, Unless the library name will be changed this script should work to check any library if exists or not.

You must log in to answer this question.

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