使用apt模块更新Python本身

1 投票
2 回答
548 浏览
提问于 2025-04-16 21:57

我正在写一个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.shnext.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()

撰写回答