【问题标题】:Maintaining environment state between subprocess.Popen commands?在 subprocess.Popen 命令之间维护环境状态?
【发布时间】:2011-05-28 10:08:36
【问题描述】:

我正在为我们的系统编写一个部署引擎,其中每个项目都指定了他的自定义部署说明。

节点在 EC2 上运行。

其中一个项目依赖于第三方应用程序的源代码版本。

具体来说:

cd /tmp
wget s3://.../tools/x264_20_12_2010.zip
unzip x264_20_12_2010.zip
cd x264_20_12_2010
./configure
make
checkinstall --pkgname=x264 --pkgversion "2:0.HEAD" --backup=no --deldoc=yes --fstrans=no --default

目前我正在使用 boto 的 ShellCommand(它在内部使用 subprocess.Popen)来执行此操作,这看起来像这样:

def deploy():
        ShellCommand("apt-get remove ffmpeg x264 libx264-dev")
        ShellCommand("apt-get update")
        ShellCommand("apt-get install -y build-essential checkinstall yasm texi2html libfuse-dev fuse-utils libcurl4-openssl-dev libxml2-dev mime-support libfaac-dev libjack-jackd2-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libvorbis-dev libvpx-dev libx11-dev libxfixes-dev libxvidcore-dev zlib1g-dev")

        ShellCommand("cd /tmp")
        s3cmd_sync("s3://.../tools/x264_20_12_2010.zip", "/tmp/x264_20_12_2010.zip")
        ShellCommand("unzip x264_20_12_2010.zip")
        ShellCommand("cd x264_20_12_2010")
        ShellCommand("./configure")
        ShellCommand("make")
        ShellCommand(r'checkinstall --pkgname=x264 --pkgversion "2:0.HEAD" --backup=no --deldoc=yes --fstrans=no --default')

遗憾的是这失败了,因为cd /tmp 适用于子进程,这意味着一旦我返回父进程并发出第二个 ShellCommand exeenv 是从父进程继承的,这让我认为我需要一些执行框架shell 命令将在同一个子进程中应用所有命令而不会丢失上下文。

此问题的推荐解决方案是什么?请注意,命令行执行应用程序的日志记录非常重要(没有它怎么调试?),这就是我喜欢 ShellCommand 的原因...(如果有兴趣,请参阅 boto 日志记录)。

谢谢你,
马克西姆。

【问题讨论】:

    标签: python command-line amazon-ec2 subprocess shellexecute


    【解决方案1】:
    1. 想想 os.chdir("DIRECTORY") 而不是 Popen("cd DIRECTORY")

    2. 也许最好不要为每个命令执行一个新的 shell:只需编写一个多行 shell 脚本

    deploy_commands = """apt-get foo apt-get 栏 光盘巴兹;嘘蝙蝠"""

    通过 Popen(deploy_commands, shell=True) 结束执行。

    但是请阅读 Popen 文档中关于不转义不受信任的参数的安全警告。

    【讨论】:

      【解决方案2】:

      我最终这样做了

      def shell_script(appname, *commands):
              workspace = tempfile.mkdtemp(prefix=appname + '-')
              installer = open(workspace + "/installer.sh", 'w')
      
              installer.write("#!/bin/bash\n")
              installer.write("cd " + workspace + "\n")
              for line in commands:
                      installer.write(line + "\n")
              ShellCommand("chmod u+x " + installer.name)
              installer.close()
              ShellCommand(installer.name)
      

      【讨论】:

        猜你喜欢
        • 2016-01-04
        • 1970-01-01
        • 1970-01-01
        • 2017-01-10
        • 2010-11-29
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多