Process, OS and CLI Tools

By Syncfusion®, Inc. · Last updated

The process object (argv, env, platform, arch, version, pid, cwd, uptime and process events), environment files with --env-file and process.loadEnvFile, standard input, output and error, TTY detection and shell piping, exit codes, process.exit versus process.exitCode, the exit and beforeExit events, signals such as SIGINT and SIGTERM, the os module, and building command-line tools with a shebang, the bin field, util.parseArgs, help output, util.styleText and npm link.

Process, OS and CLI Tools

Process = one running program. Every time you type node app.js, the computer starts a new process.

  • The process object describes your running program.
  • It holds the arguments, the settings and the input and output channels.
  • The os module describes the computer the program runs on.
  • With both, you can build your own command-line tools.

Simple lesson: process is about your program, and os is about the computer.

A Real-World Example

Think of the school's exam-paper printing room.

  • The clerk gets an order slip: "Class 8, Maths, 40 copies". These are the arguments.
  • A notice on the wall says "Use A4 paper". This is an environment setting.
  • Papers come out of the printer tray. This is the output.
  • If the paper runs out, the clerk writes "FAILED" on the slip. This is the exit code.
  • If the principal shouts "Stop!", the clerk finishes the current page and switches off. This is a signal.

What You Will Learn

In this lesson, you will learn:

  1. process.argv, process.env and other program facts
  2. .env files with --env-file and process.loadEnvFile()
  3. stdin, stdout, stderr and shell piping
  4. Exit codes, process.exit() and process.exitCode
  5. The exit and beforeExit events
  6. Signals such as SIGINT and SIGTERM
  7. The os module
  8. Building a CLI tool: shebang, bin, parseArgs, help output and colours

The process Object

  • process.argv = the words of the command, as text.
  • process.env = the environment variables, as text.
  • process.platform and process.arch = the operating system and the processor type.
  • process.version and process.versions = the Node.js version, and the versions of V8, libuv and more.
  • process.pid = the process id number given by the operating system.
  • process.cwd() = the folder the program was started from. process.chdir(dir) changes it.
  • process.uptime() = how many seconds the program has been running.
  • process.on(event, fn) = listen to process events, such as exit or SIGINT.

Environment Variables

Environment variable = a named setting given to a program from outside, such as PORT=3000.

  • Read them with process.env.NAME.
  • They are always text, or undefined when missing.
  • Give a default with ??, and turn numbers into numbers with Number().
  • Keep secrets, like passwords, in environment variables, never in code.

Add .env to .gitignore before your first commit. A password in Git history stays there even after you delete the file.

.env Files

.env file = a plain text file of NAME=value lines, one setting per line.

  • node --env-file=.env app.js loads it before the program starts.
  • process.loadEnvFile(".env") loads it from inside the program.
  • Add .env to .gitignore. Commit a .env.example with the names but no real secrets.

Simple lesson: read settings from process.env, give them defaults, and load local ones from .env.

Standard Streams

Every process has three channels.

  • stdin (standard input) = text coming in, from the keyboard or from another program.
  • stdout (standard output) = normal output. console.log writes here.
  • stderr (standard error) = error output. console.error writes here.
  • process.stdout.write(text) = write text without adding a new line.

Piping and Redirecting in the Shell

  • node app.js > report.txt = send stdout into a file.
  • node app.js 2> errors.txt = send stderr into a file.
  • node app.js < names.txt = feed a file into stdin.
  • cat names.txt | node app.js = feed another program's output into stdin.
  • Because errors go to stderr, > report.txt keeps them out of the report.

TTY Detection

TTY = a real terminal window that a person types into.

  • process.stdout.isTTY is true when a person sees the output in a terminal.
  • It is undefined when output goes to a file or a pipe.
  • Tools use this to add colours only for people, not for files. In this lab, output is not a TTY.

Simple lesson: stdout for results, stderr for problems, stdin for input from other programs.

Animation: text flows in through stdin, normal output leaves through stdout, and errors leave through stderr stdinkeyboard or file node app.jsyour program stdoutconsole.log stderrconsole.error

Every program has three streams: one in, two out.

Exit Handling

Exit code = a number the process gives back when it ends.

  • 0 = success.
  • Any other number = failure. 1 is the usual "something went wrong".
  • Shells and build servers read the exit code to decide what to do next.

process.exit() vs process.exitCode

  • process.exit(1) = stop right now. Waiting timers, writes and network calls are cut off.
  • process.exitCode = 1 = remember the code, and let the program finish its work first.
  • Prefer process.exitCode. Use process.exit only when you must stop at once.

Shells read the exit code. node check.js && node deploy.js runs the deploy only when the check exits with 0.

The exit and beforeExit Events

  • beforeExit = the event loop is empty. You may still start more async work here.
  • exit = the process is ending. Only sync code runs here.
  • beforeExit does not fire after process.exit() or a crash.

Simple lesson: exit code 0 means success, and process.exitCode is safer than process.exit().

Signals

Signal = a short message from the operating system to a process.

  • SIGINT = "interrupt". Sent when you press Ctrl + C.
  • SIGTERM = "please stop". Sent by process managers and containers when they stop a program.
  • SIGKILL = "stop now". It cannot be caught.
  • Listen with process.on("SIGINT", fn). Then Node.js no longer exits by itself. You must call process.exit().
  • process.kill(pid, "SIGTERM") = send a signal to a process.

Animation: pressing Ctrl + C sends SIGINT, the program saves its work and then exits with code 0 Ctrl + C SIGINT handlersave attendance exit(0), clean

Without a handler, Node.js stops at once and the work is lost

A signal handler gives the program a moment to clean up.

Click ▶ Run, then press Press Ctrl + C in the panel on the right.

  • Without the handler, the program would stop at once with exit code 130.
  • With the handler, it saves its work and chooses its own exit code.

Simple lesson: catch SIGINT and SIGTERM to save work, then exit yourself.

The os Module

node:os tells you about the computer.

  • os.platform(), os.arch() = the same as process.platform and process.arch.
  • os.cpus() = one entry per processor core.
  • os.totalmem() and os.freemem() = memory in bytes.
  • os.homedir(), os.tmpdir(), os.hostname() = the home folder, the temp folder and the computer's name.
  • os.networkInterfaces() = the network cards and their addresses.
  • os.EOL = the end-of-line text: \n on Mac and Linux, \r\n on Windows.

The lab shows values of a pretend computer. On your own computer, the numbers will be yours.

Simple lesson: use os to adapt your program to the computer it runs on.

Building CLI Tools

CLI tool = a program you run from the terminal by name, such as npm or git.

  1. Shebang line = #!/usr/bin/env node as the first line. It tells Mac and Linux to run the file with Node.js.
  2. Executable file = run chmod +x report.js on Mac and Linux. Windows uses the bin field instead.
  3. The bin field = in package.json, maps a command name to your file: "bin": { "report-card": "./report.js" }.
  4. npm link = installs your tool on your own computer, so you can type report-card anywhere while you build it.

Parsing Arguments with util.parseArgs()

  • options = the flags your tool knows. short gives a one-letter form, such as -c 8.
  • positionals = the plain words, such as student names.
  • Help output = show usage when asked with --help, or when input is missing.
  • styleText("bold", text) = colours and styles for the terminal. It skips them when NO_COLOR is set or output is not a TTY.
  • Unknown flags = parseArgs throws ERR_PARSE_ARGS_UNKNOWN_OPTION, which protects you from typos.

Always print help for --help, and when required input is missing. It is the first thing a new user tries.

Simple lesson: a shebang, a bin entry and parseArgs turn a script into a real command.

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
process.env.PORT + 1Environment values are numbersThey are text. Use Number()"3000" + 1 gives "30001"
Committing .env to GitIt is just a settings fileCommit .env.example onlyPasswords leak
Calling process.exit() right after writing outputExit waits for writesSet process.exitCode insteadThe last lines may be lost
Printing errors with console.logOutput is outputUse console.error for problemsErrors end up inside the saved report
A SIGINT handler that never exitsNode.js still stops by itselfCall process.exit() in the handlerCtrl + C does nothing
Reading process.argv[0] as the first wordYour words start at 0They start at index 2You get the path to Node.js

TL;DR

  1. process.argv = command words. Your own start at index 2.
  2. process.env = settings as text. Load local ones with --env-file=.env.
  3. stdin, stdout, stderr = input, output and error channels.
  4. Exit code = 0 is success, anything else is failure.

    • prefer process.exitCode = 1 over process.exit(1)
  5. beforeExit = loop is empty. exit = sync goodbye.
  6. SIGINT = Ctrl + C. SIGTERM = polite stop. Handle them to clean up.
  7. os = facts about the computer.
  8. CLI tool = shebang + bin + parseArgs + help output.

Check Yourself

Exercises

What to Remember

  • process describes your program. os describes the computer.
  • Arguments and environment variables are always text.
  • Keep secrets in .env locally, and never commit them.
  • Results go to stdout, problems go to stderr.
  • Exit code 0 means success. Prefer process.exitCode to process.exit().
  • Handle SIGINT and SIGTERM to finish cleanly.
  • parseArgs, a shebang and a bin entry make a real CLI tool.

Next: Path and File System. You will build file paths safely and read, write and organise files.