はじめに
C#でコンソールアプリケーションを作成していたとき、以下のようにパイプで入力を受け取れたらなと思いました。
# プロジェクトを利用するパターン $ echo "Hello, World!" | dotnet run # ビルド済みのConsole Appを利用するパターン $ echo "Hello, World!" | ./SampleApp
そのやり方を見つけたのでメモしておきます。
やり方
一番簡単な方法は以下のように記述することです。
while (Console.ReadLine() is { } s) { Console.WriteLine($"Input: {s}"); }
$ echo "Hello, World!" | dotnet run Input: Hello, World!
Console.ReadLineは読み取る行がなくなった(macならcontrol + c)ときにnullを返します。
Console.ReadLine メソッド (System) | Microsoft Learn
パイプを利用しないときの対策
パイプを利用するとそのまま処理が終了しますが、単純にdotnet runを実行すると入力待ちになります。(Console.ReadLineがあるので当たり前ですが...)
ただ以下のようにパイプもできるし、引数でも受け取れるようにしたくのが大体だと思います。
$ echo "Hello, World" | dotnet run $ dotnet run "Hello, World!"
これを実現するにはConsole.IsInputRedirectedを利用します。
Gets a value that indicates whether input has been redirected from the standard input stream.
// DeepL
入力が標準入力ストリームからリダイレクトされたかどうかを示す値を取得する。
Console.IsInputRedirected Property (System) | Microsoft Learn
if (Console.IsInputRedirected) { // 「echo "Hello, World!" | dotnet run」を実行した場合、標準入力はリダイレクトされている while (Console.ReadLine() is { } s) { Console.WriteLine($"Input(IsInputRedirected is true): {s}"); } } else { // 「dotnet run "Hello, World!"」を実行した場合、標準入力はリダイレクトされていない foreach (var arg in args) { Console.WriteLine($"Input(IsInputRedirected is false): {arg}"); } }