Search code examples
pythonpython-2.7macos-sierra

Why this temp file cannot be run by subprocess.check_output in python?


I am trying to create a python script to drive a docker process.

Here is my code:

def make_docker_images_build_file(fileobj):
    script = """#!/usr/bin/env bash
# Build the base image
`aws ecr get-login`
docker build -t converter . -f Dockerfile-base

"""

    fileobj.write(script)
    os.chmod(fileobj.name, 0770)


def build_docker_images():
    # create a temp file
    docker_script = tempfile.NamedTemporaryFile(prefix='docker', mode="w+", delete=False)
    make_docker_images_build_file(docker_script)
    print docker_script.name
    rc = subprocess.check_output([docker_script.name], shell=True)
    print rc

When I run it, I got these output:

/var/folders/lx/nt0ltk0n6rb7zk90b_xcr8wh0000gn/T/docker4bgHmk
   # <- blank line 

I checked the permission and it is fine.

-rwxrwx---  1 antkong  staff  304  2 Jun 14:41 /var/folders/lx/nt0ltk0n6rb7zk90b_xcr8wh0000gn/T/docker4bgHmk

If I run the script directly, it works as expected.

I have tried with or without shell parameter, but python simply did not execute the script.

Any suggestion why it fails?


Solution

  • To start with you have an space between # and ! in your shebang line, remove it first.

    Secondly as you're on a POSIX system you don't need to shell=True if the script being executed already contains a shebang line.

    Note that it is recommended to pass the command as a string when shell=True is present.

    Lastly make sure the content is getting written to the file by either adding a fileobj.flush() call after write or better use context-manager.

    Working version:

    def make_docker_images_build_file(fileobj):
        script = """#!/usr/bin/env bash
    # Build the base image
    `aws ecr get-login`
    docker build -t converter . -f Dockerfile-base
    
    """
    
        fileobj.write(script)
        os.chmod(fileobj.name, 0770)
    
    
    def build_docker_images():
        # create a temp file
        with tempfile.NamedTemporaryFile(prefix='docker', mode="w+", delete=False) as docker_script:
            make_docker_images_build_file(docker_script)
        print docker_script.name
        rc = subprocess.check_output([docker_script.name])
        print rc