如何在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中:
- 创建包含输入内容的临时文件
- 将该文件复制到Docker容器
- 修改Python代码读取该文件的内容,而非标准输入
内容的提问来源于stack exchange,提问作者Velt
相关产品推荐
相关产品推荐

