Python3 Linux发行版读取系统版本
开发机环境切换到openEuler,测试了一下宝塔的功能,除了因为发行版问题基本上mysql,nginx,php的安装都需要编译安装以外。其实就没什么问题了,甚至连docker都是正常的
但是系统版本的显示是有问题的,很令人难受。
通过f12,一步步推导出处理这部分的代码在/www/server/panel/class/public.py文件中
查看源代码,宝塔这里的检测看得出来是改了好几版了……太多的if else嵌套了
def get_os_version(): ''' @name 取操作系统版本 @author hwliang<2021-08-07> @return string ''' p_file = '/etc/.productinfo' if os.path.exists(p_file): s_tmp = readFile(p_file).split("\n") if s_tmp[0].find('Kylin') != -1 and len(s_tmp) > 1: version = s_tmp[0] + ' ' + s_tmp[1].split('/')[0].strip() else: version = readFile('/etc/redhat-release') if not version: version = readFile('/etc/issue').strip().split("\n")[0].replace('\\n','').replace('\l','').strip() else: version = version.replace('release ','').replace('Linux','').replace('(Core)','').strip() v_info = sys.version_info try: version = "{} {}(Py{}.{}.{})".format(version,os.uname().machine,v_info.major,v_info.minor,v_info.micro) except: version = "{} (Py{}.{}.{})".format(version,v_info.major,v_info.minor,v_info.micro) return xsssec(version)
通过阅读源代码,发现如果没有检测到/etc/.productinfo和/etc/redhat-release,就转用/etc/issue,但是openEuler这里的/etc/issue文件写的是:
[muwinds@localhost ~]$ cat /etc/issue Authorized users only. All activities may be monitored and reported.
何况这种检测方法太过狭隘了。
发现宝塔在这个文件导入了os包,可以用os_popen的方法使用系统命令查看更为完整的/etc/os-release文件
[muwinds@localhost ~]$ cat /etc/os-release NAME="openEuler" VERSION="22.03 (LTS-SP3)" ID="openEuler" VERSION_ID="22.03" PRETTY_NAME="openEuler 22.03 (LTS-SP3)" ANSI_COLOR="0;31"
我们可以尝试取PRETTY_NAME所在的行数,通过得到的行数用sed命令取到数据,并去掉引号和PRETTY_NAME=这两个字符
试一下:
import os fp = open("/etc/os-release","r") f_body = fp.read() find_prettyname = f_body.find('PRETTY_NAME') line_prettyname = f_body[:find_prettyname].count('\n')+1 version =os.popen('sed -n {}p {}'.format(line_prettyname, '/etc/os-release')).read().replace('"','').replace('PRETTY_NAME=','')
效果显著
试着导入宝塔,如果不报错并且能正常显示说明没啥问题:
没问题!