引子关于mintupgrade
执行逻辑思考
引子一年前电脑安装了linux mint 19版本,前几天心血来潮,想着升级到最新的版本20.2。于是就按照教程使用命令行升级的方式(mintupgrade check/download/upgrade),升级完成之后,系统变砖了。这下傻眼了~~~
所以后续经过一系列的PE操作备份,U盘启动盘制作,重新安装linux mint,最后升级到新的版本了,但是系统里面的很多软件、设置均需要重新配置,所以一切都 重头开始了
今天突然想着,之前用mintupgrade 这个命令升级之后为啥出现问题,一看脚本正好是python的,所以想着了解一下。
关于mintupgrade该命令位于linuxmint 系统的 /usr/bin/mintupgrade中,利用脚本编辑器打开之后。
结构如下:
顶层结构包含标准的变量:
ORIGIN = "Linux Mint 19.3 'Tricia'"` ORIGIN_CODENAME = "tricia" ORIGIN_base_CODENAME = "bionic" DESTINATION = "Linux Mint 20 'Ulyana'" DESTINATION_CODENAME = "ulyana" DESTINATION_base_CODENAME = "focal" # 以下还有其他
一个python 类 MintUpgrade 及几个工具函数 usage, write_tabfile等。
执行逻辑在脚本的 __name__== '__main__'语句块中:
# 首先脚本执行的第一步,判断是否用root账号执行,脚本不允许用root或者sudo账号执行
if os.getuid() == 0:
print ("")
print ("Please don't run this command as root or with elevated privileges.")
print ("")
sys.exit(1)
# 清空命令行中的输出,避免其他输出对本次升级造成影响
os.system("clear")
# 判断输入参数是否满足数量要求,一旦不满足,直接调用usage函数,直接输出帮助信息。
if len(sys.argv) != 2:
usage()
command = sys.argv[1]
if command == "help":
usage()
# 根据命令行中输入的command初始化 MintUpgrade实例
# 需要注意的是,MintUpgrade初始化的时候,还会涉及到一些信息检查,如检查mint信息,版本之类等。
upgrader = MintUpgrade(command)
# 根据命令行中输入command的不同,执行不同的函数,从类的涉及上来看,如果已经是将command传入类中,那么可以再内部直接执行一个逻辑,而不需要用if elif来进行判断。
if command == "restore-sources":
upgrader.restore_sources()
elif command == "check":
upgrader.prepare()
upgrader.check()
upgrader.restore_sources()
elif command == "download":
upgrader.prepare()
upgrader.download()
upgrader.restore_sources()
elif command == "upgrade":
upgrader.prepare()
upgrader.download()
upgrader.upgrade()
else:
usage()
思考
关于升级这一块,可以考虑将command设计到类中,从而实现根据不同的command在初始化的时候就执行对应的功能,修改如下:
#班门弄斧一下,忽略其他代码
class MintUpgrade():
def __init__(self, mode):
...
# 直接根据命令获取对应的函数,如果没有取到值,则用usage函数调用获取帮助信息
getattr(self, r'run_{mode.replace("-", '_')}', 'usage')()
def run_check(self):
self.prepare()
self.check()
self.restore_sources()
def run_download(self):
self.prepare()
self.download()
self.restore_sources()
def run_upgrade(self):
self.prepare()
self.download()
self.upgrade()
def run_restore_sources(self):
self.restore_sources()
def usage(self):
usage()
...
# 这样设计之后,在命令行执行就可以安装这样的方式运行了
MintUpgrade(command)



