pyenv安装包python总失败?

2,522 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

虽然是五月的尾巴,但是竟然也算6月更文呢!就很棒哟~😄

前言

身为一个前端小菜鸟,总是有一个飞高飞远的梦想,因此,每点小成长,我都想要让它变得更有意义,为了自己,也为了更多值得的人

开开心心学技术大法~~

开心

来了来了,他真的来了~

正文

what与why

因为python2版本和3版本差异巨大,且每一个python小版本都会有api的调整,随着python迭代的越来越庞大,一个合理有效的python版本管理器的出现就很有必要了。

我们今天的主角pyevn就是专门做这个事情的。

我们知道pyenv是什么与干什么的,接下来就要知道他是怎样用的、

安装pyenv

1、安装pyenv,安装很简单,需要用到homoebrew这个mac专用的软件包管理器。

brew install pyenv

如果mac没有安装homebrew那需要先安装一下才可以使用brew命令。

安装homebrew直接输入以下命令

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

更多homebrew安装方法

使用pyenv

1、安装完成后可以查看pyenv的版本及其支持的指令:

pyenv                        
pyenv 2.0.6
Usage: pyenv <command> [<args>]

Some useful pyenv commands are:
   --version   Display the version of pyenv
   activate    Activate virtual environment
   commands    List all available pyenv commands
   deactivate   Deactivate virtual environment
   exec        Run an executable with the selected Python version
   global      Set or show the global Python version(s)
   help        Display help for a command
   hooks       List hook scripts for a given pyenv command
   init        Configure the shell environment for pyenv
   install     Install a Python version using python-build
   local       Set or show the local application-specific Python version(s)
   prefix      Display prefix for a Python version
   rehash      Rehash pyenv shims (run this after installing executables)
   root        Display the root directory where versions and shims are kept
   shell       Set or show the shell-specific Python version
   shims       List existing pyenv shims
   uninstall   Uninstall a specific Python version
   version     Show the current Python version(s) and its origin
   version-file   Detect the file that sets the current pyenv version
   version-name   Show the current Python version
   version-origin   Explain how the current Python version is set
   versions    List all Python versions available to pyenv
   virtualenv   Create a Python virtualenv using the pyenv-virtualenv plugin
   virtualenv-delete   Uninstall a specific Python virtualenv
   virtualenv-init   Configure the shell environment for pyenv-virtualenv
   virtualenv-prefix   Display real_prefix for a Python virtualenv version
   virtualenvs   List all Python virtualenvs found in `$PYENV_ROOT/versions/*'.
   whence      List all Python versions that contain the given executable
   which       Display the full path to an executable

See `pyenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/pyenv/pyenv#readme

2、查看当前系统激活使用的python版本

study/python/auto_import_jira on  master [!?] via 🐍 system took 2s 
➜ pyenv version
​
system (set by /Users/babytree/.pyenv/version)

3、查看当前机器已经安装了哪些python版本

tudy/python/auto_import_jira on  master [!?] via 🐍 system 
➜ pyenv versions
* system (set by /Users/babytree/.pyenv/version)

4、安装指定的python版本

#查看python版本列表
pyenv install --list
​
#安装3.6.0版本
pyenv install -v 3.6.0
​
# 卸载
pyenv uninstall 3.6.0
​
#安装/卸载完成后必须rehash database
pyenv rehash

5、切换python版本

#系统全局用系统默认的Python比较好,不建议直接对其操作
#设置全局的 Python 版本,通过将版本号写入 ~/.pyenv/version 文件的方式。
pyenv global system
​
# 设置面向程序的本地版本,通过将版本号写入当前目录下的 .python-version 文件的方式。
# 通过这种方式设置的 Python 版本优先级较 global 高。pyenv 会从当前目录开始向上逐级查找 .python-version 文件,直到根目录为止。
#若找不到,就用 global 版本。
pyenv local 2.7.10
​
# 设置面向 shell 的 Python 版本,通过设置当前 shell 的 PYENV_VERSION 环境变量的方式。
# 这个版本的优先级比 local 和 global 都要高。--unset 参数可以用于取消当前 shell 设定的版本。
pyenv shell 3.5.0
​
​
#取消某版本切换
pyenv shell --unset

优先级关系:shell——local——global

以上是正常的安装和使用流程,但是pyenv安装python不同版本时很容易出现各种错误,接下来是我遇到的问题与解决方法

安装时遇到的问题

1.我通过pyenv在线安装

pyenv install 3.6.0
# 或者
pyenv install -v 3.6.0

安装时一直报 genoration什么的一个错误

2.然后我试了下pyenv的离线安装

ls ~/.pyenv/
mkdir ~/.pyenv/cache  # cache目录不存在则创建
wget https://npm.taobao.org/mirrors/python/3.6.0/Python-3.6.0.tar.xz -P ~/.pyenv/cache/
pyenv install -v 3.6.0

上面的命令是先创建一个@/.pyenv/cache的目录,然后通过wget将淘宝镜像上的pythone指定版本的压缩包安装到本地刚才创建的~/.pyenv/cache

这里注意下,如果网上其他地方也有些上面的步骤,但是有一个地方是写错的,就是wget安装的目标路径没有定到~/.pyenv/cache/上,有的写的是.pyenv/cache/。所以这里到时候离线安装时要注意下。

另外还要注意一点就是,我自己尝试的 pyenv install -v 3.6.0 跟 pyenv install 3.6.0 的效果是有点差距的,具体原因我也没搞明白,只是通过实践发现pyenv install -v 3.6.0pyenv install 3.6.0更加靠谱,出错概率更小,速度也更快。不带-v的很容易在前两步就卡死,而带-v的就更容易走到下面的步骤。

安装之后报一个sendfile的错误

Installing Python-3.8.2...
python-build: use tcl-tk from homebrew
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
​
BUILD FAILED (OS X 11.4 using python-build 2.1.0-22-g4b82f575)
​
Inspect or clean up the working tree at /var/folders/pm/dn2npfg9655293t4nkvfwx3r0000gn/T/python-build.20211027185823.74700
Results logged to /var/folders/pm/dn2npfg9655293t4nkvfwx3r0000gn/T/python-build.20211027185823.74700.log
​
Last 10 log lines:
clang -fno-strict-aliasing -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include -I/usr/local/include -L/usr/local/lib -I/usr/local/opt/openssl/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include  -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include -I/usr/local/include -L/usr/local/lib -I/usr/local/opt/openssl/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include  -std=c99 -Werror=implicit-function-declaration  -I./Include/internal  -I. -I./Include -I/usr/local/opt/readline/include -I/usr/local/opt/readline/include -I/Users/a302/.pyenv/versions/3.8.2/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl/include -I/usr/local/opt/nss/include -I/usr/local/opt/icu4c/include  -I/usr/local/opt/libarchive/include -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/ -I/usr/local/opt/sqlite/include -I/usr/local/opt/readline/include -I/usr/local/opt/readline/include -I/Users/a302/.pyenv/versions/3.8.2/include -I/usr/local/opt/zlib/include -I/usr/local/opt/openssl/include -I/usr/local/opt/nss/include -I/usr/local/opt/icu4c/include  -I/usr/local/opt/libarchive/include -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/ -I/usr/local/opt/sqlite/include  -DPy_BUILD_CORE_BUILTIN  -DPy_BUILD_CORE_BUILTIN -I./Include/internal -c ./Modules/posixmodule.c -o Modules/posixmodule.o
clang: warning: argument unused during compilation: '-L/usr/local/lib' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-L/usr/local/lib' [-Wunused-command-line-argument]
./Modules/posixmodule.c:9197:15: error: implicit declaration of function 'sendfile' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        ret = sendfile(in, out, offset, &sbytes, &sf, flags);
              ^
1 error generated.
make: *** [Modules/posixmodule.o] Error 1
make: *** Waiting for unfinished jobs....
1 warning generated.
​

3.解决sendfile的问题

接着我查了一些资料,尝试以下命令,把3.8.2换成自己要安装的python版本

CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" pyenv install --patch 3.8.2 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch?full_index=1)

这次终于是安装成功了!

总结来说,应该是pyenv的在线安装流程太长了,中间任一个步骤出现错误,都会导致python下载失败,因为pyenv安装包不只是将python安装到本机,还包括配置一系列的环境。所以很容易出错,而将python包先安装到本地,在通过pyenv解析本地安装的包,出错概率就更小一点。

pyenv切换版本时遇到的问题

pyenv查看到的版本跟python -V 查看的版本不一致。

image.png

可以看到,我在本地直接pythen -V和通过python version看到的不一样。

这个时候只需要配置pyenvshell环境配置即可。

echo 'eval "$(pyenv init --path)"' >> ~/.zprofile
​
echo 'eval "$(pyenv init -)"' >> ~/.zshrc

上面的命令意思是将xxx的字符串内容插入到xxxx的指定文件中。

因为是更改了bashzsh的配置,所以记得要source ~/.zshrc ~/.zprofilesoruce ~/.bashrc ~/.bashfile

如果依然不行,继续将以下命令输入终端

export PATH="$(pyenv root)/shims:$PATH"eval "$(pyenv init --path)"
eval "$(pyenv init -)"
​
​
if command -v pyenv 1>/dev/null 2>&1; then
    eval "$(pyenv init --path)"
fi

也要source

再打印,发现ok了

image.png

结语

往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎~)😄」