C#启动子进程时控制台输出丢失问题排查(UnityCI Docker容器下Unity批处理场景)
问题分析与解决方案
我一眼就看到了你的C#代码里的参数拼接错误,这是导致输出丢失的核心原因,另外还有几个小细节需要调整,咱们一步步来:
1. 核心问题:Bash命令的参数解析错误
你在C#里构造的Bash参数是:
Arguments = $"-c unity-editor \"{argsString}\""
这会让Bash执行的命令变成:
unity-editor "-projectPath myPath -executeMethod myMethod -logFile -"
也就是说,Unity会把整个带引号的字符串当成一个单独的参数来处理,而不是拆分出-projectPath、myPath等多个参数。Unity根本没接收到正确的命令参数,自然不会产生预期的输出。
修正方法
正确的做法是直接把完整的Unity命令作为-c的参数,用外层双引号包裹整个命令,避免空格导致的解析问题:
Arguments = $"-c \"unity-editor {argsString}\""
2. 补充:重定向标准错误输出
你的UnityCI脚本里用了xvfb-run -ae /dev/stdout,这个参数是把XVFB的错误输出重定向到标准输出,但Unity本身的错误日志可能还是会输出到stderr。你当前的C#代码里RedirectStandardError = false,这会导致这部分输出丢失。建议把它设为true,并同样监听错误输出:
RedirectStandardError = true, // 然后添加错误输出的监听 proc.ErrorDataReceived += OnErrorDataReceived; proc.BeginErrorReadLine(); // 对应的处理方法 void OnErrorDataReceived(object obj, DataReceivedEventArgs args) { if(!string.IsNullOrEmpty(args.Data)) Console.WriteLine(args.Data); }
3. 额外验证:解决输出缓冲问题
有些程序在非交互式终端下会缓冲输出,导致内容不会实时显示。你可以尝试在Unity命令前添加stdbuf来强制关闭缓冲:
Arguments = $"-c \"stdbuf -o0 unity-editor {argsString}\""
stdbuf -o0会让标准输出无缓冲,确保内容能实时传递到你的C#进程。
完整修正后的C#代码
void StartProcess() { string argsString = "-projectPath myPath -executeMethod myMethod -logFile -"; ProcessStartInfo startInfo = new ProcessStartInfo { FileName = "/bin/bash", Arguments = $"-c \"stdbuf -o0 unity-editor {argsString}\"", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, }; using Process proc = Process.Start(startInfo); proc.OutputDataReceived += OnOutputDataReceived; proc.ErrorDataReceived += OnErrorDataReceived; proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); proc.WaitForExit(); } void OnOutputDataReceived(object obj, DataReceivedEventArgs args) { if(!string.IsNullOrEmpty(args.Data) && args.Data.StartsWith("[")) Console.WriteLine(args.Data); } void OnErrorDataReceived(object obj, DataReceivedEventArgs args) { if(!string.IsNullOrEmpty(args.Data)) Console.WriteLine(args.Data); }
为什么直接用Bash执行没问题?
因为你直接在Bash里输入unity-editor -projectPath...时,Bash会自动把空格作为参数分隔符,正确拆分每个参数传递给Unity脚本。而C#里错误的引号包裹破坏了这个拆分逻辑,导致Unity无法正确执行命令。
内容的提问来源于stack exchange,提问作者Rurre
相关产品推荐
相关产品推荐

