使用apt模块更新Python本身
我正在写一个Python脚本,这个脚本会在EC2机器上运行,作为用户数据脚本。我想知道怎么才能像在命令行中使用bash命令那样,升级机器上的软件包。
$ sudo apt-get -qqy update && sudo apt-get -qqy upgrade
我知道可以在Python中使用apt
这个包来实现这个功能:
import apt
cache=apt.Cache()
cache.update()
cache.open(None)
cache.upgrade()
cache.commit()
问题是,如果Python本身也是被升级的软件包之一,那升级后该怎么处理呢?有没有办法在升级后重新加载解释器和脚本,继续之前的操作?
现在我唯一的选择是用一个shell脚本作为我的用户数据脚本,专门用来升级软件包(可能还包括Python),然后再进入Python执行剩下的代码。我希望能省去使用shell脚本的这一步。
2 个回答
0
使用链式调用。
#!/bin/sh
cat >next.sh <<'THEEND'
#!/bin/sh
#this normally does nothing
THEEND
chmod +x next.sh
python dosomestuff.py
exec next.sh
在你的Python应用程序里,你可以写一个shell脚本来完成你需要的操作。在这个例子中,这个shell脚本的作用是升级Python。因为它是在Python关闭后运行的,所以不会有冲突。实际上,next.sh
可以启动同一个(或者另一个)Python应用。如果你交替使用两个shell脚本first.sh
和next.sh
,你可以将这些调用链式连接起来,想连接多少个都可以。
0
我想我明白了:
def main():
import argparse
parser = argparse.ArgumentParser(description='user-data-script.py: initial python instance startup script')
parser.add_argument('--skip-update', default=False, action='store_true', help='skip apt package updates')
# parser.add_argument whatever else you need
args = parser.parse_args()
if not args.skip_update:
# do update
import apt
cache = apt.Cache()
cache.update()
cache.open(None)
cache.upgrade()
cache.commit()
# restart, and skip update
import os, sys
command = sys.argv[0]
args = sys.argv
if skipupdate:
args += ['--skip-update']
os.execv(command, args)
else:
# run your usual code
pass
if __name__ == '__main__':
main()