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

如何在Unity中创建支持Docker -it标签的终端执行Python代码

问题:Unity中通过Docker执行Python代码无法使用交互式终端(报错"The input device is not TTY")

我希望在Unity中借助Docker执行Python代码,但无法使用输入命令。尝试创建PTY却未能成功,始终报错**"The input device is not TTY"**。请问是否有办法创建可使用Docker -it 标签的终端?

以下是我的实现代码:

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class DockerController : MonoBehaviour
{
    public TMP_InputField pythonCodeInputField;
    public Button runButton;
    public SimplifiedConsole simplifiedConsole;
    private Button TerminalButton;

    void Start()
    {
        runButton.onClick.AddListener(ExecutePythonCodeInDocker);
    }

    private void GetOrInstantiateConsoleModule()
    {
        simplifiedConsole = FindObjectOfType<SimplifiedConsole>();
        if (simplifiedConsole == null)
        {
            TerminalButton.onClick.Invoke();
            simplifiedConsole = FindObjectOfType<SimplifiedConsole>();
        }
    }

    private void ExecutePythonCodeInDocker()
    {
        string pythonCode = pythonCodeInputField.text;
        GetOrInstantiateConsoleModule();
        // Save the Python code to a temporary file
        string tempFileName = Path.GetTempFileName();
        File.WriteAllText(tempFileName, pythonCode);

        // Copy the file to the Docker container
        ProcessStartInfo copyInfo = new ProcessStartInfo();
        copyInfo.FileName = "docker";
        copyInfo.Arguments = $"cp \"{tempFileName}\" pyc_container:/tmp/code.py";
        copyInfo.UseShellExecute = false;
        copyInfo.CreateNoWindow = true;

        Process copyProcess = new Process();
        copyProcess.StartInfo = copyInfo;
        copyProcess.Start();
        copyProcess.WaitForExit();

        // Execute the Python code in the Docker container
        ProcessStartInfo execInfo = new ProcessStartInfo();
        execInfo.FileName = "docker";
        execInfo.Arguments = "exec -it pyc_container python /tmp/code.py";
        execInfo.RedirectStandardOutput = true;
        execInfo.RedirectStandardError = true;
        execInfo.RedirectStandardInput = true;
        execInfo.UseShellExecute = false;
        execInfo.CreateNoWindow = true;

        Process execProcess = new Process();
        execProcess.StartInfo = execInfo;
        execProcess.OutputDataReceived += Process_OutputDataReceived;
        execProcess.ErrorDataReceived += Process_ErrorDataReceived;
        execProcess.Start();
        execProcess.BeginOutputReadLine();
        execProcess.BeginErrorReadLine();

        // Clean up the temporary file
        File.Delete(tempFileName);
    }

    private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null)
        {
            // Call the method in the SimplifiedConsole class
            simplifiedConsole.UpdateOutputText(e.Data + "\n");
        }
    }

    private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null)
        {
            // Call the method in the SimplifiedConsole class
            simplifiedConsole.UpdateOutputText(e.Data + "\n");
        }
    }
}

解决方案

报错原因

docker exec -it中的-t参数会要求Docker分配一个伪终端(TTY),但Unity通过Process启动的进程并没有关联真实的终端设备,因此触发"The input device is not TTY"错误。

方案一:移除t参数,保留交互式输入能力

将Docker执行命令中的-it改为-i,仅保留标准输入的交互性(无需分配TTY)。修改后的代码片段如下:

// Execute the Python code in the Docker container
ProcessStartInfo execInfo = new ProcessStartInfo();
execInfo.FileName = "docker";
// 替换-it为-i,避免TTY分配要求
execInfo.Arguments = "exec -i pyc_container python /tmp/code.py";
execInfo.RedirectStandardOutput = true;
execInfo.RedirectStandardError = true;
execInfo.RedirectStandardInput = true;
execInfo.UseShellExecute = false;
execInfo.CreateNoWindow = true;

Process execProcess = new Process();
execProcess.StartInfo = execInfo;
execProcess.OutputDataReceived += Process_OutputDataReceived;
execProcess.ErrorDataReceived += Process_ErrorDataReceived;
execProcess.Start();
execProcess.BeginOutputReadLine();
execProcess.BeginErrorReadLine();

// 如果Python代码需要接收输入,通过StandardInput传递
// 示例:发送输入并关闭输入流
// execProcess.StandardInput.WriteLine("your_input_content");
// execProcess.StandardInput.Close();

// 可选:等待进程执行完毕
execProcess.WaitForExit();

方案二:使用PTY模拟工具(Windows环境)

如果必须依赖TTY特性,可以使用winpty工具来模拟伪终端,包装Docker命令。修改后的Arguments如下:

execInfo.Arguments = "winpty docker exec -it pyc_container python /tmp/code.py";

注意:需要确保winpty已安装且在系统PATH中,或者指定winpty.exe的完整路径。

方案三:非交互式输入替代

如果不需要实时交互,可以将输入内容预先写入临时文件,让Python代码从文件读取输入。例如在Unity中:

  1. 创建包含输入内容的临时文件
  2. 将该文件复制到Docker容器
  3. 修改Python代码读取该文件的内容,而非标准输入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:47:14