liveBook · Manning

Os package

As explained in Go in Action, Second Edition

The os package is a Go standard-library package that provides platform-independent interfaces for operating-system functionality, including files, processes, and environment variables.

A CLI needs more than transformation logic: it must read inputs, write results, inspect its environment, and signal failure. Go’s os package provides a platform-independent interface to those operating-system functions, so application code can use the same interface on Windows, macOS, and Linux. section 10.4

Read a word-count input file

Use os.ReadFile(filename) to load a file into memory, check the returned error, then convert the bytes to a string for strings.Fields. To choose the file at launch rather than editing the program, take its name from os.Args[1]; os.Args[0] is the command itself, so check that an argument was supplied before indexing. section 2.6.1 section 2.7.1

For a larger CLI, os also handles the boundary between processing code and the system:

  • Use os.Stdin for input, os.Stdout for normal output, and os.Stderr for diagnostics. An io.Reader or io.Writer can then refer either to a standard stream or to an opened file. section 10.4
  • Use os.Open and os.Create for selected file paths; close opened files when finished. os.Stat can check that an input exists, is regular, and is nonempty before opening it. section 10.4
  • Use os.LookupEnv or os.Getenv for environment-based settings. Use os.Exit(0) for success or a nonzero status for failure, but remember that os.Exit skips deferred cleanup. section 10.4
Listing 10.13 Using flags as guards on our application
func main() {

    inputFlag := flag.String("f", "", "Input file path")
    outputFlag := flag.String("o", "", "Output file path")

    ...

    var input io.Reader = os.Stdin
    var output io.Writer = os.Stdout

    if inputFlag != nil && *inputFlag != "" {
        file, err := os.Open(*inputFlag) #1
        if err != nil {
            fmt.Fprintf(os.Stderr, "Error opening input file: %v\n", err)
            os.Exit(1)
        }
        defer file.Close()
        input = file
    }

    if outputFlag != nil && *outputFlag != "" {
        outFile, err := os.Create(*outputFlag) #2
        if err != nil {
            fmt.Fprintf(os.Stderr, "Error creating output file: %v\n", err)
            os.Exit(1)
        }
        defer outFile.Close()
        output = outFile
    }

    // Pass to process function
    if err := process(input, output); err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }
}

The file-selection example starts with stdin and stdout, then replaces either stream when its corresponding flag names a file. That keeps conversion logic working with readers and writers rather than separate file-only paths. section 10.4

How Go in Action, Second Edition covers it

How deep it goes
Works through file reading and CLI stream selection, then addresses metadata checks and exit behavior without examining operating-system internals.
Examples
Uses a file-based word counter and a JSON/XML conversion CLI with selectable input and output files.
What it assumes
Assumes familiarity with Go imports, errors, and main functions while introducing os operations through concrete CLI examples.
What you can do after
Apply it via Go’s os package to read inputs, select streams, inspect settings, and report CLI failures.
How it connects
Links command-line arguments, io.Reader and io.Writer, file metadata, environment variables, and exit codes.

Also explained in

Compare how 3 books explain os package →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Action, Second Edition. The section links point to the parts of the book it draws on.