Bug 12552 - Console.ReadLine() does not read from console if stdout (but not stdin) is redirected
Summary: Console.ReadLine() does not read from console if stdout (but not stdin) is re...
Alias: None
Product: Class Libraries
Classification: Mono
Component: mscorlib (show other bugs)
Version: 2.8.x
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2013-06-04 23:51 UTC by Greg Najda
Modified: 2017-10-30 22:00 UTC (History)
5 users (show)

See Also:
Is this bug a regression?: ---
Last known good build:


Description Greg Najda 2013-06-04 23:51:17 UTC
Run the following program copied from my other bug report with stdout redirected but not stdin. On .NET it waits for a keypress, then exits.

C:\Users\Greg\Documents\Programming\consoletest\consoletest\bin\Debug>consoletest.exe > output.txt

output.txt contains:

Press a key
Key pressed: 78

On Mono in Linux, it exits immediately.

greg@Kubuntu:~/dev/consoletest/consoletest/bin/Debug$ mono consoletest.exe > output.txt
greg@Kubuntu:~/dev/consoletest/consoletest/bin/Debug$ cat output.txt
Press a key
Key pressed: 0
greg@Kubuntu:~/dev/consoletest/consoletest/bin/Debug$ mono --version
Mono JIT compiler version (Debian

This also prevents using programs that use ReadKey() with utilities like tee because piping to tee redirects stdout.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace consoletest
    class Program
        static void Main(string[] args)
            Console.WriteLine("Press a key");
            bool exceptionThrown = false;
            ConsoleKeyInfo key = new ConsoleKeyInfo();
                key = Console.ReadKey(intercept: true);
            catch (InvalidOperationException)
                // This is the documented behavior when reading from a non-console stdin
                Console.WriteLine("InvalidOperationException thrown.");
                exceptionThrown = true;
            if (!exceptionThrown)
                // Mono instead returns a ConsoleKeyInfo with a Key value of 0.
                Console.WriteLine("Key pressed: {0}", (int)key.Key);
Comment 1 Greg Najda 2013-06-09 18:02:14 UTC
Console.ReadKey(bool intercept) calls ConsoleDriver.ReadKey(bool intercept) which calls IConsoleDriver.ReadKey(bool intercept). The static constructor of ConsoleDriver determines which implementation of IConsoleDriver is used for console operations.

static ConsoleDriver ()
	// Put the actual new statements into separate methods to avoid initalizing
	// three classes when only one is needed.
	if (!IsConsole) {
		driver = CreateNullConsoleDriver ();
	} else if (Environment.IsRunningOnWindows) {
		driver = CreateWindowsConsoleDriver ();
	} else {
		string term = Environment.GetEnvironmentVariable ("TERM");

		// Perhaps we should let the Terminfo driver return a
		// success/failure flag based on the terminal properties
		if (term == "dumb"){
			is_console = false;
			driver = CreateNullConsoleDriver ();
		} else
			driver = CreateTermInfoDriver (term);

IsConsole effectively returns (Isatty (MonoIO.ConsoleOutput) && Isatty (MonoIO.ConsoleInput))

In other words, if stdout or stdin or both are not a console, then NullConsoleDriver is used. This prevents you from doing input console operations if stdout is redirected. A possible fix would be to have TermInfoDriver and WindowsConsoleDriver correctly handle the case where stdin or stdout is not a console and use TermInfoDriver/WindowsConsoleDriver even if one of stdin or stdout is not a console. Maybe even get rid of NullConsoleDriver entirely and only use TermInfoDriver/WindowsConsoleDriver and have them be aware of whether stdin and stdout are actually a console.
Comment 2 Miguel de Icaza [MSFT] 2015-06-12 12:32:03 UTC
This needs a new driver InputConsoleProvider that would allow input, but remove the Terminfo features
Comment 3 Vladimir Kargov 2016-04-09 09:53:30 UTC
Seems like this issue reveals itself in ASP.NET Core apps since stdout/stderr are always redirected:

Example of usage that would cause the problem:
Comment 4 Ludovic Henry 2017-10-30 22:00:51 UTC
I can reproduce with Mono (2017-10/863ab3cb164).

I compile the repro case provided in https://bugzilla.xamarin.com/show_bug.cgi?id=12552#c0 and  run the following command:

> mcs repro.cs
> mono repro.exe | cat

The expected output is :

> Press a key
> Key pressed: 65 // After pressing "a"

The actual output is:

> Press a key
> Key pressed: 0

Note You need to log in before you can comment on or make changes to this bug.