You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本在Docker容器中执行带重定向的echo命令无法生成目标文件的问题求助

Why can't I create a file with content using echo content > /tmp/foo in a Docker container via exec_run?

Problem Description

I've written the following code to test Docker containers with unittest:

import subprocess
import docker
import unittest

class DockerContainerHost(object):
    def execute(self, command):
        self._container.exec_run(command)

class Tester(unittest.TestCase):
    def test_twoHostsOneFile(self):
        with DockerContainerHost() as host1, DockerContainerHost() as host2:
            host1.execute('echo content > /tmp/foo')

if __name__ == '__main__':
    unittest.main()

Everything else works fine, but when running host1.execute('/bin/echo content > /tmp/foo'), the file /tmp/foo isn't created in the container. I can successfully create an empty file with touch /tmp/foo, but I need to generate a file with specified content. How can I fix this?

Solution

Ah, I see the issue here! When you use exec_run without enabling shell mode, the redirection operator > isn't being interpreted by a shell—it's just passed as a literal argument to the echo command. That's why touch works (it doesn't need shell processing) but your echo command fails to create the file.

Here are a few reliable fixes:

1. Enable shell execution in exec_run

Modify your execute method to run the command through a shell. This lets the shell handle the redirection:

def execute(self, command):
    # Add shell=True to let the shell process redirection
    self._container.exec_run(command, shell=True)

This is the simplest fix for your existing code. Just note that if you're executing untrusted command strings, enabling shell=True can introduce security risks (like shell injection attacks), so use this cautiously if your input isn't controlled.

2. Explicitly call a shell to run your command

If you don't want to enable shell=True globally, you can wrap your command in sh -c to explicitly invoke a shell:

host1.execute('sh -c "echo content > /tmp/foo"')

This achieves the same result as the first fix, but limits shell usage to specific commands. Make sure to handle quotes correctly—if your content includes quotes, you may need to escape them or use different quote delimiters.

3. Write the file directly without relying on shell redirection

For a more secure and programmatic approach, you can write content to the file using the Docker SDK's input stream feature, avoiding shell processing entirely:

class DockerContainerHost(object):
    def execute(self, command):
        self._container.exec_run(command)
    
    def write_file(self, file_path, content):
        # Use cat with stdin to write content directly to the file
        exec_result = self._container.exec_run(
            f'cat > {file_path}',
            stdin=True,
            tty=False,
            detach=False
        )
        # Write the content to the command's stdin
        exec_result.output.write(content.encode())

Then use it in your test like this:

host1.write_file('/tmp/foo', 'content')

This method is safer because it doesn't involve shell parsing, and it's easier to handle dynamic content without worrying about escaping issues.


内容的提问来源于stack exchange,提问作者PawelBuchajczuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:23:11