脚本用途

将系统默认的python2.6版本到最新的python2.7.13,原有的python2.6继续保存

使用方法

复制下面的代码保存到upgradePython.sh,并赋可执行权限chmod +x upgradePython.sh

失败处理

亲测通过,但不排除某些特殊情况下遇到错误无法成功。

注意:因为下载python与pip源码速度一般都较慢,导致整个脚本长时间卡住,建议先手动下载完源码,再将源码与脚本放在同一目录,然后再执行脚本,这样体验会好很多。

#!/bin/bash
# 脚本用途,将系统默认的python2.6版本到最新的python2.7.13,原有的python2.6继续保存

# 彩色输出,定义变量
red="\e[0;31m"
green="\e[0;32m"
yellow="\e[0;33m"
endColor="\e[0m"

# 判断当前是否已经是2.7.13版本,如果是直接退出【未完成,无法实现】
#python_version=`python -V`
#echo ${python_version}
#if [[ "${python_version}" == "Python 2.7.13" ]]
#then
#  echo -e "${green}当前已经是${python_version}版本,不需要升级${endColor}"
#  exit 0
#else
#  echo -e "${green}当前python版本:${python_version}${endColor}"
#fi


# 展示当前python版本
echo -e "${green}脚本用途,将Centos系统默认的python升级到最新的python2.7.13版,原有的python继续保存${endColor}"
echo -e "${green}当前python版本${endColor}"
python -V
read -p "按任意键继续升级,按键【control + C】退出升级" var


# 检查当前用户是否有root权限
res=`id|grep -c root`
if [[ ${res} < 1 ]]
then
  echo -e "${red}当前脚本需要root权限才能正确执行,请先切换到root用户${endColor}"
  exit 1
fi


# 安装依赖包
echo -e "${green}通过yum安装依赖包:wget gcc Python-devel libffi-devel openssl-devel readline readline-devel gettext${endColor}"
yum -y install wget gcc Python-devel libffi-devel openssl-devel readline readline-devel gettext
# 顺便修复wget下载时进度条刷屏的BUG
if [[ -f /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo ]]
then
  msgunfmt /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo -o - | sed 's/eta(英国中部时间)/ETA/' | msgfmt - -o /tmp/zh_CN.mo
  mv /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo.init
  cp /tmp/zh_CN.mo /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo
else
  msgunfmt /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo.back -o - | sed 's/eta(英国中部时间)/ETA/' | msgfmt - -o /tmp/zh_CN.mo
  mv /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo.back /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo.back.init
  cp /tmp/zh_CN.mo /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo.back
fi


# 下载函数
function download(){
    filename=$1
    download_url=$2
    md5str=$3
    while [ 1 ]
    do
        # 判断python源码文件是否存在
        if [[ -f ${filename} ]]
        then
            file_md5=`md5sum ${filename}|cut -d ' ' -f 1`
            if [[ "x${md5str}" == "x${file_md5}" ]]
            then
                echo -e "${green}本地【${filename}】文件正确,不用下载${endColor}"
                break
            else
                echo -e "${red}本地【${filename}】文件不完整,重新下载${endColor}"
                echo -e "${red}期望的md5值:${md5str}${endColor}"
                echo -e "${red}实际的md5值:${file_md5}${endColor}"
                rm -f ${filename}
            fi
        fi

        # 下载python
        echo -e "${yellow}开始下载【${filename}】源码${endColor}"
        echo -e "${yellow}wget --no-check-certificate ${download_url}${endColor}"
        wget --no-check-certificate ${download_url}

        # 判断下载的文件是否正确
        if [[ -f ${filename} ]]
        then
            file_md5=`md5sum ${filename}|cut -d ' ' -f 1`
            if [[ "x${md5str}" == "x${file_md5}" ]]
            then
                echo -e "${green}【${filename}】md5校验成功,继续……${endColor}"
                break
            else
                echo -e "${red}【${filename}】md5校验失败,重新下载${endColor}"
                echo -e "${red}期望的md5值:${md5str}${endColor}"
                echo -e "${red}实际的md5值:${file_md5}${endColor}"
                rm -f ${filename}
            fi
        else
            echo -e "${red}【${filename}】下载失败,重新下载${endColor}"
        fi
    done
}


# 下载源码
cd ~
# download python
python_file='Python-2.7.13.tgz'
python_md5='17add4bf0ad0ec2f08e0cae6d205c700'
python_url='https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tgz#md5=17add4bf0ad0ec2f08e0cae6d205c700'
download ${python_file} ${python_url} ${python_md5}
# download setuptools
setuptools_file='setuptools-12.0.3.tar.gz'
setuptools_md5='f07e4b0f4c1c9368fcd980d888b29a65'
setuptools_url='https://pypi.python.org/packages/source/s/setuptools/setuptools-12.0.3.tar.gz#md5=f07e4b0f4c1c9368fcd980d888b29a65'
download ${setuptools_file} ${setuptools_url} ${setuptools_md5}
# download pip
pip_file='pip-9.0.1.tar.gz'
pip_md5='35f01da33009719497f01a4ba69d63c9'
pip_url='https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9'
download ${pip_file} ${pip_url} ${pip_md5}


# 安装python
echo -e "${yellow}安装python2.7.13到/usr/local/python2.7.13${endColor}"
tar -zxvf Python-2.7.13.tgz
cd Python-2.7.13
# 编辑源码,去掉某些注释,否则后续安装setuptools与pip时会报错
sed -i '166ireadline readline.c -lreadline -ltermcap' Modules/Setup.dist
sed -i '219iSSL=/usr/local/ssl' Modules/Setup.dist
sed -i '221i_ssl _ssl.c \\' Modules/Setup.dist
sed -i '223i-DUSE_SSL\ -I\$\(SSL\)\/include\ -I\$\(SSL\)\/include\/openssl\ \\' Modules/Setup.dist
sed -i '225i-L\$\(SSL\)\/lib\ -lssl\ -lcrypto' Modules/Setup.dist
sed -i '471izlib zlibmodule.c -I\$\(prefix\)/include -L\$\(exec_prefix\)/lib -lz' Modules/Setup.dist
./configure --prefix=/usr/local/python2.7.13
make && make install


# 判断安装是否正确
if [[ "$?" == "0" ]]
then
  echo -e "${green}安装python2.7.13成功${endColor}"
else
  echo -e "${red}安装python2.7.13失败${endColor}"
  echo -e "${red}请参考下面链接地址进行手动安装:${endColor}"
  echo ''
  exit 1
fi


# 备份及创建软链接
today=`date +%s`
echo -e "${green}备份原有yum到/usr/bin/yum.bak${today}${endColor}"
cp /usr/bin/yum /usr/bin/yum.bak${today}

echo -e "${green}更新/usr/bin/yum文件中调用的python版本为/usr/bin/python2.6${endColor}"
sed -i '1i#!/usr/bin/python2.6' /usr/bin/yum
sed -i '2d' /usr/bin/yum

echo -e "${green}备份/usr/bin/python到/usr/bin/python.bak${today}${endColor}"
mv /usr/bin/python /usr/bin/python.bak${today}

echo -e "${green}软链接python2.7.13到/usr/bin/python${endColor}"
ln -s /usr/local/python2.7.13/bin/python2.7 /usr/bin/python

echo -e "${green}升级后python版本:${endColor}"
python -V


# 安装setuptools
echo -e "${yellow}开始安装:setuptools-12.0.3${endColor}"
cd ~
tar -zxvf setuptools-12.0.3.tar.gz
cd setuptools-12.0.3
python setup.py install


# 安装pip
echo -e "${yellow}开始安装:pip-9.0.1${endColor}"
cd ~
tar -zxvf pip-9.0.1.tar.gz
cd pip-9.0.1
python setup.py install
ln -s /usr/local/python2.7.13/bin/pip /usr/bin/pip
echo -e "${green}当前pip版本:${endColor}"
pip -V

交流区

脚本中有一段未完成:判断当前版本是否已经是python2.7.13,如果是自动退出。因为在脚本中无法获取到python的当前版本。有解决的请在评论区告知我,谢了。


shell编程中父子进程消息传递问题?

为什么下面的命令执行后变量pip_version有值:

pip_version=`pip -V`
echo ${pip_version}

而换成python命令变量version就没有值了:

version=`python -V`
echo ${version}

弄明白上述问题,可能会解决一直困扰了我很久的问题:

jenkins job中调用shell脚本时,日志可以实时打印出来,但调用python脚本时,日志却不能实时打印,显示的时机不可控,有时一个任务跑的时间较长,想卡在某处,又看不到日志