C# Academy · Lesson

CLI ergonomics

Build friendly command-line tools: clear help, short flags, exit codes, stdout vs stderr, basic parsing, and simple verbosity.

Lesson 3 of 38 steps

CLI ergonomics is a free C# Academy lesson on CoddyKit. This is lesson 3 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 3 lessons in total.

Friendly CLI basics

Goals:

  • Show help with -h/--help
  • Use clear flags (-i, -o, --verbose)
  • Return 0 on success, non-zero on error
  • Send results to stdout, diagnostics to stderr

Usage & help

Add a short usage section and accept both short and long flags; show it when input is missing.

using System;

// A tiny CLI that prints help if no args or -h/--help is passed.
public class Program
{
  static void PrintUsage()
  {
    Console.WriteLine("usage: tool -i <input> [-o <output>] [--verbose]");
    Console.WriteLine("options:");
    Console.WriteLine("  -i, --input     input file path (required)");
    Console.WriteLine("  -o, --output    output file path (optional)");
    Console.WriteLine("  -h, --help      show help");
    Console.WriteLine("      --verbose   print extra diagnostics to stderr");
  }

  public static void Main(string[] args)
  {
    if (args.Length == 0 || args[0] == "-h" || args[0] == "--help")
    {
      PrintUsage();
      Environment.ExitCode = 0;
      return;
    }

    Console.WriteLine("OK: arguments received"); // placeholder success
  }
}

Flags & exit codes

Return non-zero on invalid flags; keep messages short and specific. Print success to stdout.

using System;

// Minimal manual parsing for beginners (no external libs).
public class Program
{
  static void Error(string msg)
  {
    Console.Error.WriteLine("error: " + msg);
    Environment.ExitCode = 1; // non-zero means failure
  }

  public static void Main(string[] args)
  {
    string input = null;
    string output = null;

    for (int i = 0; i < args.Length; i++)
    {
      string a = args[i];
      if (a == "-i" || a == "--input")
      {
        if (i + 1 >= args.Length) { Error("missing value for " + a); return; }
        input = args[++i];
      }
      else if (a == "-o" || a == "--output")
      {
        if (i + 1 >= args.Length) { Error("missing value for " + a); return; }
        output = args[++i];
      }
      else if (a == "-h" || a == "--help")
      {
        Console.WriteLine("usage: tool -i <input> [-o <output>]");
        return;
      }
      else
      {
        Error("unknown option: " + a);
        return;
      }
    }

    if (input == null) { Error("input is required (-i)"); return; }

    // Success path: write result to stdout
    Console.WriteLine("Processed " + input + (output == null ? "" : (" -> " + output)));
    Environment.ExitCode = 0;
  }
}

Stdout vs stderr

Put results on stdout (pipeable), and diagnostics on stderr. Add a simple --verbose flag.

using System;

// Show separation of streams: stdout (results) vs stderr (diagnostics).
public class Program
{
  public static void Main(string[] args)
  {
    bool verbose = false;
    for (int i = 0; i < args.Length; i++) if (args[i] == "--verbose") verbose = true;

    if (verbose) Console.Error.WriteLine("info: starting work");
    // pretend to compute a number
    int result = 42;
    // Result goes to stdout so it can be piped:  tool ... > out.txt
    Console.WriteLine(result);

    if (verbose) Console.Error.WriteLine("info: finished work");
    Environment.ExitCode = 0;
  }
}

Conventions & polish

  • Accept both short and long flags (-h/--help)
  • Use clear error messages (what is wrong + how to fix)
  • Keep default output minimal; add --verbose for details
  • Use consistent exit codes (0 success, 1 invalid args, 2 I/O failure)

Smoke tests & docs

  • Try redirection: command > out.txt and command 2> err.txt
  • Test error paths: missing file, bad args
  • Keep usage text under ~5 lines on mobile
  • Document examples: copy/paste friendly

Streams & exit codes

Quick check: Which practice improves CLI usability and shell piping?

Recap

Recap: Help on -h/--help, clear flags, proper exit codes, and separating stdout/stderr make your tools script-friendly and predictable.

Free to start

Learn C# with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
93
Lessons
346

Frequently Asked Questions

Is the “CLI ergonomics” lesson free?

Yes — the full text of “CLI ergonomics” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO. The C# Academy course includes 3 lessons in total.

What will I learn in “CLI ergonomics”?

Build friendly command-line tools: clear help, short flags, exit codes, stdout vs stderr, basic parsing, and simple verbosity. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 3.

How long does the “CLI ergonomics” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. C# scripting (dotnet script), snippets & REPL
  2. Interop basics (P/Invoke) at a glance
  3. CLI ergonomics
← Back to C# Academy