Although graphical interfaces can do more and more, many advanced operations still need to be handled from the command line.
This page briefly introduces some ways to use the command line.
Basics
Windows comes with two command-line interfaces. The Command Prompt (cmd) is the older and relatively simple one. PowerShell is the newer command-line interface, with richer built-in functionality but greater bulk. Both interfaces can be found in the Start menu.
Unix-like systems (including macOS and Linux, referred to as Unix below) come in two kinds: with and without a graphical interface. If the system has a graphical interface (for example, macOS or a Linux installation with GNOME, KDE, or another graphical interface), the command line can generally be opened through a program called Terminal (or Console). Systems without a graphical interface automatically enter the command line after startup completes.
The command line on Windows looks like this:
C:\Users\chtholly>
Commands entered on the command line appear after >.
C:\Users\chtholly>echo "Hello World!"
The command line on Unix looks like this (using Debian/Ubuntu as an example; command lines on other systems are broadly similar):
chtholly@seniorious:~$
Commands entered on the command line appear after $.
chtholly@seniorious:~$ echo "Hello World!"
If root is used to log in to the command line on Unix, $ is replaced with #:
root@seniorious:~# apt-get install gcc
A path is displayed before the >, $, or # on the command line. This path is the working directory, or current directory. On Unix, the current directory is sometimes displayed in a form such as ~/folder; the ~ at the beginning is the home directory of the currently logged-in user. The location of user chtholly's home directory differs between systems: on Linux it is /home/chtholly, while on macOS it is /Users/chtholly.
Syntax and common commands1
File-system-related
First, here are two ways to describe locations in a file system: relative paths and absolute paths.
-
Relative path: describe a location relative to the current path. For example, if the current path is
~/folder,./a.cpprefers to the file~/folder/a.cpp. As the current path changes, the location described by a relative path may also change. -
Absolute path: describe a location using its complete path. For example,
~/folder/a.cppis an absolute path. The location described by an absolute path does not change as the current path changes.Windows/Unix uses
.for the current directory and..for the parent directory of the current directory. In particular, Unix uses~for the user's home directory (note that~is expanded by the shell and may therefore be unavailable elsewhere).
On Unix, use the pwd command to print the current directory (this command also exists in Windows PowerShell, but not in the Windows Command Prompt; see the note below for details). On Windows/Unix, the cd <目录> command switches the current directory. For example, cd folder switches to the folder subdirectory of the current directory, while cd .. switches to the parent directory of the current directory.
Special note for the Windows Command Prompt
The Windows Command Prompt has no pwd command, but a cd command with no arguments can be used as an approximation.
Also note that when using cd to switch directories in the Windows Command Prompt, if the drive letter of the target directory differs from that of the current directory, the current directory does not change. You can type the drive letter of the target path once more, or use cd /d <目录> to switch the drive letter at the same time. The two methods look as follows in the command line:
C:\Users\Libaray>cd D:\Codes
C:\Users\Libaray>D:
D:\Codes>
C:\Users\Libaray>cd /d D:\Codes
D:\Codes>
On Windows, use dir to list the files in the current directory. On Unix, the command for listing files is ls. In particular, PowerShell can use the same ls command as Unix.
On Windows, use md <目录> or mkdir <目录> to create a new directory, and rd <目录> or rmdir <目录> to delete a directory. On Unix, the two commands are mkdir and rmdir, respectively. Note that a directory must be empty before it can be deleted with rd or rmdir. To delete a non-empty directory (and all files under it), run rm -r <目录> on Unix or rd /s <目录> on Windows.
Redirection
I compiled a program that reads from standard input and writes to standard output. However, the input and output files are both very large. Is there a way to redirect input to a specified input file and output to a specified output file?
The following command does this:
$ command < input > output
For example, ./prog < 1.in > 1.out makes prog read data from 1.in in the current directory and overwrite 1.out with the program's output.
Warning
The original contents of 1.out will be overwritten. To append to the end of the original output file, use >>, that is, redirect output with ./prog >> 1.out.
Note that PowerShell supports output redirection only, not input redirection.
In fact, most OJs use this kind of redirection mechanism. A contestant's submitted program uses standard input and output; through redirection, the program can read from a given input file and write to a specified output file, after which it can be evaluated by comparing files.
Executing programs
For an executable program or batch script, simply enter its filename directly on the command line to execute it.
Of course, when executing a file, the command line does not search through every directory. The environment variable PATH describes the scope of the command-line search path, and the command line looks for the target file in the paths in PATH.
On Windows, the current directory is also in the command line's default search scope. For example, entering the hello command on Windows executes hello.exe in the current directory. However, PowerShell does not search the current directory for executables by default (which is consistent with Unix), so in PowerShell you need to use a relative or absolute path to call an executable in the current directory, such as .\hello.exe; otherwise, you will see the following error:
PS> hello
hello: The term 'hello' is not recognized as a name of a cmdlet,
function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that
the path is correct and try again.
Suggestion [3,General]: The command hello was not found, but does exist
in the current location. PowerShell does not load commands from the
current location by default. If you trust this command, instead type:
".\hello". See "get-help about_Command_Precedence" for more details.
On Unix, the current directory is not in the command line's default search scope, so the command to execute the hello program in the current directory becomes ./hello:
$ hello
hello: command not found
$ ./hello
Hello World!
Summary
The usage introduced above is only a small part of command-line commands; many commands have not been covered. Enter the help command help on the command line to query all basic commands and their uses.
The following table compares commands on Windows and Unix for reference.
| Category | Windows | Unix |
|---|---|---|
| List files | dir | ls |
| Change directory | cd | cd |
| Create directory | md | mkdir |
| Delete directory | rd | rmdir |
| Compare files | fc | diff |
| Copy files | copy | cp |
| Move files | move | mv |
| Rename files | ren | mv |
| Delete files | del | rm |
Compiling/debugging from the command line
See: Command-Line Compilation and Debugging.
Command-line tips
Autocompletion
Completion is one of the basic functions provided by a shell. It is mainly used to reduce the amount of typing needed on the command line and the probability of typos.
In general, the shortcut for completion is Tab. After it is pressed, the shell completes information based on the characters already entered.
Different shells provide different completion capabilities.
The following are the completion capabilities of common shells2:
| Shell | Completion capabilities (completion scope) |
|---|---|
| cmd (the traditional Windows console) | File paths |
| PowerShell | File paths, command names in PATH, built-in command names, function names, command parameters; fuzzy matching and automatic correction |
| Bash | File paths, command names in PATH, built-in command names, function names, command parameters |
| Zsh | File paths, command names in PATH, built-in command names, function names, command parameters; fuzzy matching, automatic correction, and suggestions |
| Fish | File paths, command names in PATH, built-in command names, function names, command parameters; fuzzy matching, displaying parameter functions during completion, automatic correction, and suggestions |
Note
Some PowerShell features require the PSReadline Module to be loaded or require PowerShell ISE.
Bash completion generally requires a package named bash-completions for full functionality; completion files for some software are included with the software package.
Zsh's complete completion functionality requires user-predefined files (usually installed with the Zsh package or the corresponding software package).
Fish provides good and complete completion under its default configuration, but completion files for some software not officially covered are provided by the software itself.
Help documentation
Generally, programs on the command line come with "help". On Windows, it is usually obtained with command /? or command -?; on Unix-like systems (such as Linux), it is usually obtained with command --help or command -h (but "help" on BSD is often excessively brief and difficult to use).
In addition, Unix-like systems have a "manual" that can be obtained with man command, which is generally more detailed than "help".
built-in time and GNU time
When testing program running time, we can usually use the time command.
However, there are actually two corresponding commands in the system: one is built into some shells (such as Bash), and the other is GNU time (a separate piece of software). There are differences between them.
In Bash, directly using time generally invokes the built-in version. We can control its output format with the TIMEFORMAT environment variable; for example, setting it to %3lR outputs the real running time to three digits of precision, while %3lU outputs the user-space running time to three digits of precision.3
To invoke the GNU version of time, use \time or /usr/bin/time, but its output format is not easy to read. We can append the -p parameter (that is, use \time -p) to obtain readable output.
Pipes
Suppose we now have two programs, A and B, both using standard input and output. How can we redirect A's output to B's input?
We can use the redirection method mentioned above: first redirect A's output to a temporary file, and then redirect B's input to that temporary file.
However, this method is inefficient. It not only requires creating a new file, but disk I/O can also become a bottleneck, and the two programs cannot run at the same time: B must wait for A to finish before starting. Is there a better method?
Yes: a pipe, which is also very simple to use:
$ A | B
This creates a pipe in memory, and then starts both programs at the same time. Each time program A outputs, its output is redirected into the pipe, while the pipe itself does not store data (it actually has a very small buffer). Before B reads, A's output operation is blocked; after B reads the data, A's output can continue. This elegantly solves the problems above: there is no disk I/O, both programs run simultaneously, and not much extra memory is used to store intermediate results.
Named pipes
Sometimes we do not merely want to redirect one program's output to another's input. For example, when solving an interactive I/O problem, we often need to redirect A's output to B's input and B's output to A's input; in this case, the ordinary pipe mentioned above is insufficient. Redirecting to a file cannot make the two programs run simultaneously either. What is needed is a pipe that looks like a file—a named pipe.
On Unix, use the following command to create a named pipe (using my_pipe as the name):
$ mkfifo my_pipe
If you use ls to list the files in the current directory at this point, you will find an additional file named my_pipe|. This creates a named pipe; the | after the filename indicates that it is a pipe file. You can then read from and write to this pipe just as with file redirection.
Using named pipes, we can make two programs interact as follows:
$ mkfifo input output
$ ./checker > input < output # Here > input must come first; otherwise the shell opens the output pipe first, and since this pipe currently has no data, it blocks checker from running.
$ ./my_code < input > output
After use, delete the named pipe with the rm command just as you would a regular file.
References and notes
Footnotes
-
Liu Rujia, Classic of Algorithms Competition (2nd Edition), Appendix A: Development Environment and Methods ↩