【发布时间】:2021-10-16 22:40:27
【问题描述】:
我在使用 System.Diagnostics.Process 时遇到了一个奇怪的问题(在 linux 系统上)。
每次启动进程时都会输出 ANSI 转义序列。
序列是<ESC>[?1h<ESC>=(DECCKM, DECKPAM),但这不是被调用程序产生的,我在这里使用了pwd,但是序列也是用任何其他程序创建的。
序列似乎是在进程之外生成的,因为标准和错误输出流无法获取它。
奇怪的是,它只发生在我启动虚拟主机之后!
我构建了一个最小的代码示例。
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Extensions.Hosting;
class Program
{
static int count;
static void Main(string[] args)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
execTest();
Host.CreateDefaultBuilder().Build().RunAsync(cancellationTokenSource.Token);
Thread.Sleep(2000);
execTest();
cancellationTokenSource.Cancel();
Thread.Sleep(2000);
execTest();
}
private static void execTest()
{
for (var i = 0; i < 3; i++)
{
executeCommand("pwd");
Console.WriteLine($"Exectest {++count}");
}
}
static void executeCommand(string cmd)
{
var process = new Process();
process.StartInfo.FileName = cmd;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
process.WaitForExit();
}
}
要查看效果,您需要特殊的日志记录、管道或重定向来禁用效果。
当 xterm 解释转义序列时,它们是不可见的。
因此我使用script -c myTestProg output.log; cat -A output.log
在输出中您可以看到,前三个 ExecuteTests 按预期工作,但 Exectest 4 到 9 产生了这个意外输出。
Exectest 1
Exectest 2
Exectest 3
^[[?1h^[=^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
Content root path: /home/jeb/xx/csharp-test
^[[?1h^[=Exectest 4
^[[?1h^[=Exectest 5
^[[?1h^[=Exectest 6
^[[40m^[[32minfo^[[39m^[[22m^[[49m: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
^[[?1h^[=Exectest 7
^[[?1h^[=Exectest 8
^[[?1h^[=Exectest 9
我的主要问题是我的程序使用 Microsoft.Hosting 并每秒调用一个进程,这导致我的日志文件泛滥。 即使我通过
禁用主机的输出日志记录.ConfigureLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders();
});
问题依然存在。
导致输出的原因以及如何避免或抑制输出?
System.Diagnostics.Process 和 Microsoft.Extensions.Hosting 之间的关系在哪里?
PS:序列是在Process.Start()之后产生,调用程序结束,但是在调用WaitForExit之前,用一些Thread.Sleep(100)测试
【问题讨论】:
-
看起来像是定向到控制台的彩色日志输出。
-
@KlausGütter 是的,
Microsoft.Hosting.Lifetime的info是绿色的,但^[[?1h似乎是DECCKM - Enable Cursor Keys Application Mode 和^[=是DECKPAM - Enable Keypad Application Mode,但为什么它是由@987654336 生产的@? -
您是否尝试在
appsettings.json中使用Logging.Console.DisableColors到true禁用颜色?检查此问题 Logs include control characters (in place of coloring) in Visual Studio output window when using Docker 和此 PR Add DisableColors option (#764)。或者使用环境变量ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS可能会破坏 ANSI 转义字符。 -
@ChristosLytras 感谢您的提示,但禁用颜色只会删除
info: Microsoft.Hosting.Lifetime[0]中的转义序列,但令人费解的^[[?1h^[=仍然存在。