Need to verify whether it is installed or not before the program can run.
10 Answers
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.
-
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 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 usinggrep -w ruamel.yaml
orgrep -w request
– AnthonFeb 24, 2019 at 7:29 -
pip list | grep -F mxnet-cu101
printsmxnet-cu101 1.5.0
, but not exactly where it is installed. any idea how to get the installed path? `– AnuJul 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.– AnthonJul 26, 2019 at 6:49
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
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.
-
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.– BrianMar 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.)– aschultzMay 28, 2021 at 0:56
Type in the shell: pydoc modules
.
This will list modules and you can grep the module which you want.
Found on stackoverflow here
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
-
-
1The 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. :) Jul 22, 2018 at 8:18
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.
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
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
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.
pip install
. If it's already installed, it won't install it again.