Learn from a particle physicist

Aug 30, 2016 learning Linux shell terminal

terminal and command line

Show things in a directory

A modern Linux PC looks and feels similar to a Windows PC or a Mac. You can use your mouse to click around, open files, launch programs. What we are going to cover here is how to use commands instead of a mouse to control your PC. The first command you may type into a Linux command line is probably ls. But where can you find a Linux command line? In a modern operating system, a command line is normally provided in a program generally called terminal as shown in the screenshot above. A command is simply a text string you type into this program. (MobaXterm is such a program for Windows.) You need to press Enter to execute a command. The output of the executed command is shown in the terminal and a new command line is provided below the output waiting for new input.

The ls command lists files and folders in the current directory. This is equivalent to opening the file explorer in Windows. In the latter, you can tell whether an item is a file or a directory by its icon. After executing ls in a Linux terminal, the file and folder names will be printed under the command line. There is no icon for you to tell which is a file or a folder. You can turn on an option of the ls command so that it attaches a letter after the name of an item to indicate the type of the item:

$ ls -F
file  folder/  executable*  shortcut@

The -F string after ls is used to turn on this option. I’d like to remember F as file type so that I won’t forget about it. A dash is needed IMMEDIATELY before a one-letter option. No space is allowed in between the dash and the option. A space IS needed between the command and an option though, otherwise, they’ll be regarded by Linux as a single command ls-F (which does not exist) instead of a command ls with an option -F. A final remark before we move on is that CASE MATTERS in Linux. You cannot replace F with f or ls with Ls. Actually, there is no f option for the ls command, and Ls is not a Linux command.

I put a $ symbol in front of the ls command to represent the command prompt, which are simply some text strings normally ended with $. They can be informative or funny. You can change it to your likings once you know more about Linux. The prompt is not part of the command. You don’t have to type it in your terminal when you follow this instruction. But it is a common practice to put $ in front of a command in tutorials to distinguish a command from its output printed below it.

Now let’s take a look at the output of the ls -F command. A normal file has nothing attached to its end. A folder has a slash / attached. Note that \ is called back slash and is different from /. An executable, or a program that you can run, has a * attached to its end. This is necessary because most Linux programs do not end with .exe, you need the * to tell whether an item is an executable or a normal file. A shortcut to an item located somewhere else ends with an @. It is the same as a Desktop shortcut in Windows.

A drawback of this method is that someone may regard an attached letter as part of the name of an item. He may try to do something with executable* instead of executable in the example above but only gets an error message saying that there is no file called executable*.

A better way is to show files in different colors according to their types. For example, normal file names can be shown in white, folders in blue, executables in red, shortcuts in purple, etc. as shown in the screenshot above. To achieve this, you need to turn on another option of ls, that is, --color:

$ ls --color

It is very common for a Linux command to use one dash - to indicate a one-letter option and two dashes -- to indicate a long option, such as color in this example. What if you want to turn the color display off? I know it sounds strange, but somebody does prefer black and white. It turns out that long options sometimes can take an argument. For example,

$ ls --color=never

turns the output back to black and white, where never is an argument of the color option.

Note that in a Mac, --color does not exist. You should use ls -G instead.

To learn more about the type of a file, you can use the file command:

$ file some.exe
some.exe: PE32+ executable (console) x86-64 (stripped to external PDB)

long output of ls

It is possible to check the type, the size, the modified date and time of a file by choosing detailed view in the Windows File Explorer as shown in the screenshot above. The same effect can be achieved by turning on the -l (long list) option of ls:

$ ls -l
-rw-r--r--  1 jintonic physino 12005 Jan  3 16:35 README.md
drwx------+ 1 jintonic physino     0 Sep 26  2018 mail/
lrwxrwxrwx  1 jintonic physino    34 Oct 23  2017 Dropbox -> /cygdrive/c/Users/jintonic/Dropbox/

The meaning of each column is briefly explained in the screenshot above. Detailed explanation of file permission can be found in https://www.guru99.com/file-permissions.html

The file size is shown in the unit of byte, which can be a long number for a large file. You can display it in human readable format using the h option, which can share a single - with the l option:

$ ls -lh
-rw-r--r--  1 jintonic physino 1.2G Jan  3 16:35 some.dat
-rw-r--r--  1 jintonic physino 4.3K Jan  3 16:35 file.txt

There are a few options that are normally used together with the -l option: -S sorts the output by file size, -t sorts by their last modified time.

There is an option in the Windows File Explorer to show hidden files in a directory. Similar things can be done in Linux using the a (means all) option of ls:

$ ls -a
.  ..  .bashrc  mail  README.md

The first three items start with a dot. In Linux, you can add a dot at the beginning of a file name to turn it into a hidden file. In this example, mail and README.md are normal files. .bashrc is an hidden file. The single and double dots have very special meanings. To find out, we need to combine the a and F option:

$ ls -aF
./  ../  .bashrc  mail/  README.md

From the / letter attached to the ends of them, we know that they are directories. In fact, One dot means the current directory, two dots means the parent directory. This brings us to the next section.

Change directories

The command to change to a different directory is cd. To go to the mail/ directory, you type (don’t forget Enter)

$ cd mail

Note that mail is an argument of the cd command. If you don’t have a mail/ directory, this command will complain that it cannot open this directory. To make sure that this works for you, run ls first to check what’s in your current folder. If there is a directory, replace mail with the name of that directory.

To go back to the previous directory, you have two choices. First,

$ cd ..

where .. means the parent directory as we learned from the previous section. Second,

$ cd -

where - is not part of an option. Instead, it means to go back to the previous directory. The way to remember this is to regard - as a minus sign instead of a dash. Minus means you lose your current position and go back to the previous one.

You can go into a sub-sub-directory using one command

$ cd mail/inbox

This directory chain can be as long as you want. In this case, cd .. brings you back to the mail folder, while cd - brings you back to the folder that contains mail.

Up to this point, it looks like that the ls command does not take any argument, while the cd command has to take an argument, which is not true. You can use

$ ls mail/inbox

to list mails in the mail/inbox directory. And cd without any argument will take you back to your home directory. What is the home directory? This is not a concept familiar to Windows users. Linux uses a quite different method to organize its files. To learn more, please search “Linux directory structure” in Google. In short, each Linux user gets a dedicated directory for her to store her files, which is called the user’s home directory. When the user open a terminal, the start directory is her home directory. The name of the home directory is the same as the user name. To illustrate how the user home directories are organized in Linux, let’s assume a Linux machine with two users, jack and rose:

$ cd /home
$ ls -F
jack/   rose/

The home directories for both jack and rose are placed in the same directory called /home. (Note in macOS, the home directories are placed in /User.) You may ask why this time the / is placed in front of a directory instead of after it? The leading / still represents a directory, but it is a very special one. It is the top directory of the Linux directory tree, or the root directory. It has no parent directory above it. That’s why you cannot put any string in front of it anymore. So

$ cd /
$ ls -F
bin/  boot/  etc/  home/

brings you to the root directory and show you what’s in it, where you can find the home/ directory that contains all users’ home directories.

A directory chain like mail/inbox is called a path. If a path starts with /, it is called an absolute path, since you start at the root directory. Otherwise, it is called a relative path, which starts at the current directory. So mail/inbox is a relative path, it is in the current directory, instead of in the root directory.

Suppose rose asks you to check a document in her home directory, you can do it in two ways:

$ cd /home/rose

or

$ cd ~rose

The combination of the tilde symbol ~ and rose is a shortcut to /home/rose.

A single ~ without any username following it is a shortcut to your own home directory. So

$ cd ~

is equivalent to

$ cd

A great way to use ~ can be something like this:

$ cd ~/mail/inbox

which brings you from rose’s home directly back to your email inbox located in your home directory. Note that this command cannot be typed as cd ~mail/inbox, since ~mail means the home directory of a user named mail (if there is any), while ~/mail means the mail/ directory in your own home directory.

Suppose that you’d like to get into a directory called folderWithALongName. In Windows, you just need to double click its icon in the File Explorer. While in Linux, the operation involves a lot of typing, until you learn the Tab trick, that is, the Linux command line can automatically complete a file or directory name when you press Tab after you type in the first a few letters. So cd fTab will become cd folderWithALongName automatically if there is no other file starts with f. If there is another file in the same directory called flights, nothing happens when you press Tab after f. Don’t give up yet! If you press Tab again, the command line will list all files starting with f for you to chose. You can typing a few more letters to break the ambiguity, for example fol, and then press Tab again to complete the whole name. So please make it a habit to hit Tab frequently with your left pinky when you use cd. It will save you a lot of typing.

Another advantage of using Tab to complete a file or a directory name is to make sure that you don’t type it wrong. For example, if you type cd folderw and two Tabs after it, nothing will happen, since there is no file starting with folderw. You should then check your spell and realize that you should have typed folderW instead of folderw. Such a mistake is very common in those who just switch from Windows to Linux and have not yet gotten used to the CASE SENSITIVE nature of Linux. Tab is your friend to help you avoid such mistakes.

A file name in Windows can contain space in it, for example, My Document. This is not a good idea in Linux though, since

$ cd My Document

will give you an error message cd: too many arguments. This is because the space in the command line is used to separate arguments. My and Document are separated by the space and are regarded as two different directories in this case. You cannot go to two different directories at the same time, which results in the error message.

There are two ways to solve this problem in Linux. One is to quote the file name:

$ cd "My Document"

The other is to escape the space with a back slash \:

$ cd My\ Document

The \ in front of the space turns the space to a normal space from a separator between arguments of a command. In general, \ can be used in front of special letters in a file name to turn them to normal text characters. For example, if a directory is named a "Strange" directory\, we can turn all special characters back to normal one by one using \:

$ cd a\ \"Strange\"\ directory\\

Yes, a \ in front of another \ turns the second \ to a normal character.

Remember, the Tab trick still works for names that contain special characters. So cd MyTab may become cd My\ Document automatically, which is nice.

Even though there is a solution for a file name with space in it, you should try to avoid creating such a name in Linux. Alternatives include MyDocument, My_Document or simply doc.

One more thing you may need to know before we move to the next section is the pwd command. It is used to print the working directory, or where you are right now, in case you get lost after many cd commands:

$ pwd
/home/jack/mail/trash

Show file content

Equipped with ls and cd, you can already navigate through a Linux directory tree. But when you encounter a file named README.txt, how can you see its content? In Windows, it is very easy, you just need to double click the icon, the file will then be shown in a notepad. In Linux, there are programs like notepad as well, they are called text editors. However, what we really need here is to simply view the file instead of editing it. The simplest way is to use the cat command:

$ cat README.txt

which print the contents of README.txt in the terminal. I am always wondering if there is a Linux command called dog. But no, there is none. The cat command works nicely for short files that can be shown within the terminal window. If a file is longer than what can be shown in a terminal, its contents will be flashed quickly through the terminal window until the end of it. To check the disappeared the contents, you can scroll your screen up using your mouse wheel. If it does not work, try to hold Shift and then use PageUp and PageDown to scroll up and down. Such combinations are normally written as Shift + PageUp and Shift + PageDown.

If you are only interested in part of the contents, for example, only a few lines at the beginning or end of the file, you can use head and tail commands:

$ head README.txt
$ tail README.txt

which shows the first/last 10 lines of README.txt, respectively. To specify how many lines to be shown, you can use the -n option, which works for both head and tail:

$ head -n 12 README.txt
$ tail -n 31 README.txt

In some system, -n 12 can be shortened to -12.

The cat, head and tail commands are not real viewers. There are two text viewers that you can use in Linux, more and less. less is better than more, since sometimes less is more :)

$ less README.txt

replaces the whole terminal screen with the contents of README.txt. To go back to your command line, you need to type q to quit less. Inside less, you can use PageUp and PageDown to flip pages without holding Shift. Shift+PageUp and PageDown still work, but they flip the terminal pages, instead of the less pages.

The formal name of a less page is alternate screen. It is NOT the original terminal screen (or window as I call it previously). It disappears when you quit less and you are back to the original terminal screen as if less has not printed out anything to the screen. This is a common behavior of many terminal based programs, such as text editors. You need to realize that the alternate screen is NOT the terminal screen and that they expect completely different ways of operation. For example, the less alternate screen does not understand the ls and cd commands. To see what less does understand, press h within less to check its help page.

less is completely keyboard driven, that is, you use your keyboard instead of your mouse to control it. The j key scrolls the page down by one line, the k key scrolls the page up by one line. The / key allows you to start a search of a string in README.txt. The n key is used to go to the next occurrence of the search string, N goes to the previous occurrence. It takes some practice for you to get used to these key strokes. But it is worth the effort since many Linux programs share the same hot keys.

Go back to ancient history, a keyboard at that time did not even have arrow keys. No wonder ancient programs like less can be entirely controlled by keys on the main typing keypad, which can sometimes more efficient than the mouse-driven approach.

Now that we learned how to control less, I can introduce a very important Linux command, man. It is used to show manuals of other Linux commands in less. For example,

$ man ls

displays a long description of all options that go with the ls command. To learn more about man, you can

$ man man

To know more about color related option of ls, you can press / and type color and Enter to search for the string color in the man page.

You can search for a string in a text file without even opening it in less. For example, you can print lines in README.txt that contains “some string” on your terminal screen using:

grep "some string" README.txt

Combination of commands

The output of a command in the terminal screen has a formal name, stdout, or standard output stream. Guess what, a Linux command also has a stdin to accept output stream from another command. Two Linux commands can be chained with a pipe | in between. For example, I can connect the stdout of ls to the stdin of less using |:

$ ls | less

This is useful when the output of ls is more than that can be displayed in one terminal screen. You can navigate through the long output of ls within the less alternate screen using all the less hotkeys.

Now guess what the following command chain does:

$ cat README.txt | head -20 | tail -1

It shows the 20-th line of README.txt on the terminal screen.

$ ls -l | grep exe

only prints lines that contains “exe” in the ls -l output.

grep "one" input1.txt | grep "two" intput2.txt does not make sense, because you try to provide two inputs to the second grep, one is from the previous grep through the pipe, the other one is from the file input2.txt. In this case, the second input is ignored.

The right command to search for lines in a file that contain two strings is

grep "string 1" input.txt | grep "string 2"

instead of grep "string 1" "string 2" input.txt.

It is also possible to save the output of a command into a file for detailed check sometime later using

$ ls > output.txt

You can then use less output.txt to check the output at any time you want. If there is already a file named output.txt in the current directory, its old contents will be replaced by the output of ls. The following command can be used to append the output of ls to the end of the existing contents:

$ ls >> output.txt

Now you may start to sense the infinite possibility provided by the combination of simple commands using the stdout and stdin mechanism. Please check https://www.howtogeek.com/435903/what-are-stdin-stdout-and-stderr-on-linux/ and https://www.commandlinefu.com/commands/browse/sort-by-votes to learn more.

If the output of a command is redirected to a file, it won’t show up on the terminal screen (stdout) anymore. To achieve both, you need a tee to split the data flow:

$ ls | tee output.txt

This way, the ls output appears both on the screen and in output.txt.

Create or delete things

Before you change anything, you need to understand that you can only change things in your home directory, which makes sense. If everybody can delete system files in a Linux machine, the machine will become unusable fast. If you get an error message saying “Permission denied”, run pwd to check where you are. If you are not in your home directory, type cd to go back to your home directory.

The following command creates a directory chain:

$ mkdir -p example/advanced/A1

The option -p tells mkdir to make parent directories as needed. If example/ does not exist before running the command, mkdir will just create it. If -p is ignored and example/ does not exist, mkdir will give the following error message:

cannot create directory 'example/advanced/A1': No such file or directory

The following command deletes (removes) a file:

$ rm randomFile

To delete a directory, you should first delete everything in it and then delete itself. Or you can use a -r flag to tell rm to remove everything inside together with the directory:

$ rm -r aDirectoryContaintsSomethingInIt/

If you use the -i option, rm will ask for confirmation before doing something:

$ rm -i randomFile
rm: remove regular file 'randomFile'?

press y to continue, n to quit. If you are tired pressing y for a long list of files to be deleted, you can use the -f flag to force deleting everything without confirmation:

$ rm -rf dir

It is frequently used together with -r to avoid typing y for every file in dir.

The following command moves a folder to another place. In this case, order matters. You are moving the first item, not the second one.

$ mv example/advanced/A1 example/A2

If there is already a folder called A2, the command moves A1 inside A2. The final result is that you have example/A2/A1. If there is no folder called A2, the command moves A1 from example/advanced/ to example and renames it to A2. This tells us that mv can do two things: one is to move things, the other is to rename a thing.

You can move many things at the same time. The following command moves thing1, thing2, and thing3 to the destination/ directory. The order of thing1, thing2 and thing3 does not matter, but destination/ must be the last argument.

$ mv thing1 thing2 thing3 destination

An easier way to achieve the same thing is to use a wildcard character * to represent any character in the command:

$ mv thing* destination

thing* matches thing1, thing2, thing3, and thingWhatEver if it exists.

You can also create shortcuts to your favorite folders or files using the ln (link) command. In Linux, a shortcut is called a link. The following command will create a link called simpleExample to the example/advanced/A1 folder in the current folder.

$ ln -sf example/advanced/A1 simpleExample

Please use man ln to check the meaning of the -sf flags.

Edit text files

We’ve learned how to view a text file using cat, less, etc. You need another type of programs to modify a text file. They are called text editors. If you have a file called output.txt in your current directory, try one of the following commands based on your operating system:

$ edit output.txt # in MobaXterm local terminal in Windows
$ open output.txt # in macOS terminal
$ gedit output.txt # in Ubuntu terminal

Texts after # (including # itself) are called comments, they are simply explanations of the command. You don’t have to type them into your terminal. Even if you do, you system will ignore everything from # to the end of the command line.

If there is no output.txt before you run these commands, the editors will create it. The exception is

$ edit output.txt # in MobaXterm local terminal in Windows

It looks like that you cannot create a file in MobaXterm this way. You need to first create an empty file using the touch command:

$ touch output.txt # create the file
$ edit output.txt # open it in the MobaXterm text editor

Job control

When you run gedit otuput.txt in a real Linux terminal (not in MobaXterm or macOS terminal), your terminal will wait till you quit your editor to give you another command line. If you want to have your command line back without quitting your editor, you need to go back to your terminal window, hold Ctrl and press z to suspend your editor. The suspended editor cannot be used anymore unless you use the bg command to send it to the background running job list of your terminal:

$ gedit output.txt # use <ctrl>-z to suspend gedit
$ bg # send gedit to the background job list of your terminal

After that, both your terminal and editor can be used. You can achieve this effect in one command:

$ gedit output.txt &

The & symbol directly run gedit as a background job.

You can use

$ jobs

to list all background jobs in your current terminal, and the following command to bring them back to foreground:

$ fg

man bash and search for “job control” to learn more about this topic.

Shell

You may use ls --color -hal very often. To save typing, you can create a short alias of this long command:

$ alias l='ls --color -hal'

Now you can simply type l as a command that achieves the same effect as the long version. alias without any argument lists all alias that already exist. Try it out in your terminal and you will be amazed how creative people are in creating short commands.

Unfortunately, your terminal cannot remember this setup. When you open a new terminal, all your settings are gone. In Linux, user preferences of a program are normally saved in a text file called configuration file. A user specific configuration file is normally saved in your home directory. A configuration file for everyone in a Linux machine is saved in /etc. A configuration file is normally hidden, which means that its name starts with a dot .. It is normally ended with rc. So a typical configuration file name would look like .prgrc, and it is likely to be in your home directory.

But which program is responsible for dealing with the command line? Your first guess might be the terminal. But it’s not. The terminal handles the user interface, it passes user input to a program called shell, which processes all the commands.

It is a bit confusing when we think about the roles that a termnial and a shell play. Simply put, a terminal provides a frame, where a shell exists. The size of the terminal, the font used to display the shell prompt, commands and output, as well as the mouse clicks are handled by the terminal. Key strokes will be processed first by the terminal and then sent to the shell.

The middle click of a mouse in most of the Linux terminals would actually do the job of paste, the same as the Ctrl + v combination in Windows and Cmd + v in macOS. If you don’t have the middle bottom in your mouse or touch pad, try to press the left and right bottoms at the same time, which sometimes mimic the middle bottom click. If that does not work either, a right click will most probably bring up a menu provided by the terminal, which may provide you the copy and paste options. Copy can be done by simply selecting some text in the terminal while holding the left button. Double left click on a word will select and copy the whole word. Triple click will select the whole line where the mouse is pointing to.

According to wikipedia,

a shell is a user interface for access to an operating system’s services. In general, operating system shells use either a command-line interface (CLI) or graphical user interface (GUI), depending on a computer’s role and particular operation. It is named a shell because it is a layer around the operating system kernel.

Practically, the word shell almost always refers to CLI (command Line Interface) instead of GUI (Graphic User Interface). In some sense, to learn Linux command-line is to learn how to use a shell.

There are many shells out there. If you don’t have any preference at this moment, please try to learn Bourne Again SHell, or bash in short, first because it is probably the most commonly available and used one.

The configuration file for bash is .bashrc in your home directory for a Linux machine or MobaXterm. In a MAC, ~/.bashrc is only used by XQuartz programs, which will be mentioned later. Configurations for bash that would take effect in a MAC terminal should be saved in ~./bash_profile instead. Check if you have one:

$ cd # go to your home directory
$ ls -a # list all files including hidden ones

If not, run touch .bashrc to create it and then use a text editor to open it, go to the end of it and add

alias l='ls --color -hal' # for macOS replace --color with -G

save and quit. Now open another terminal and check if you can use l in it.

What else can we save in ~/.bashrc instead of aliases? One interesting thing you can do is to setup the so-called environmental variables. They control the environment within with your commands run. Run the following command to list all environmental variables that currently take effect in your shell:

env

Normally, the list is overwhelmingly long. Let’s start with a few important ones first. First of all, I’d like to mention PS1. It controls what can be shown as the command prompt. A command prompt sometimes looks like this:

UserName@HostName:~ >

or this:

root@HostName:/ $

or something really fancy:

UserName@HostName:~ | 8:30 am | battery: 34% | :-)

Check your current setting using

env | grep PS1

If you are not satisfied with it, put the following line to your .bashrc

export PS1='\u@\h:\w\$ '

save and quit, open a new terminal to see the difference. If it is hard for you to remember the meaning of \u, \h, \w, etc., don’t worry. You can use http://ezprompt.net/ to create a good PS1 easily. If you want to use the new setup in your current shell, run

source ~/.bashrc

The effect of some of the environmental variables is not as obvious as that of PS1. To check if your setup is successful, you can use the echo command to print out the content of an environment variable (case sensitive), for example,

$ echo $SHELL # The SHELL variable saves the type of shell you are using.
$ echo $HOME # the location of your home directory
$ echo $PATH # list of directories where executables are located

Notice the $ sign in front of the variables. When you use the content of an environment variable, you need to use the $ sign. Sometimes, a pair of () is also needed to clearly mark the boundary of a variable, for example, $(SHELL).

You can use the export command to declare or change an environment variable directly in your shell and make it take effect immediately:

$ export AMadeUpEnvVariable="some random text"
$ echo $AMadeUpEnvVariable
$ export SHELL=/bin/zsh # switch to another shell
$ export SHELL=/bin/bash # switch back to use bash
$ export PS1='\u@\h:\w $' # set prompt to be UserName@HostName:PWD $

Note that there is no need to put the $ sign in front of variable when you assign a new value to it.

If you are satisfied with the result, save them in ~/.bashrc (or ~/.bash_profile in macOS) so that you don’t have to type them again next time you log in.

PATH

echo $PATH would normally give you a list like the following:

/usr/local/bin:/usr/bin:/bin

It is a list of directories separated by :. These directories contain commands (sometimes we call them executables or programs) that can be executed in a terminal. When you type in a command in your terminal, Linux will search for that command in the listed directories. If it cannot be found, an error message will be given.

The order of the directories in the list matters. The search will be performed from the left most directory to the right most. If multiple directories contain the same command, the first found command will be executed. You can use this feature to overwrite commands in system command directories. To be more specific, you can

$ mkdir ~/bin
$ export PATH=~/bin:$PATH # add your personal ~/bin/ to the front of the original $PATH list

When you put a newer version of a program in ~/bin, the system will run this program instead of the one in /bin.

You can use the which command to confirm which command you really use:

$ which ls
~/bin/ls

To use a command that is not in the $PATH list or appears in a later directory, you can call it with its full path:

$ ls # run ~/bin/ls if there is one
$ /bin/ls # run /bin/ls directly

The /sbin directory contains tools that are normally used by system administrators, but some are useful for normal users as well. Sometimes, this directory is not added to the $PATH list. You can call commands in this directory using the absolute path:

$ /sbin/ifconfig # print the IP address of the machine

Hot keys

The shell provides a set of key combinations, or shortcuts, to facilitate the editing of the command line. For example, Ctrl + a moves your cursor to the beginning of the command line, Ctrl + e moves it to the end. Search for bash shortcuts on Google for a complete list, or use the following command to print them out in your terminal:

bind -P |grep "can be found on" |less

I’d like to emphasize a few useful ones in addition to Ctrl + a and Ctrl + e:

  • Ctrl + t: toggle two letters, e.g. sl Ctrl + t becomes ls
  • Ctrl + k: delete everything after the cursor
  • Ctrl + l: clear the whole terminal screen
  • Ctrl + f / b: move the cursor forward/backward by one letter
  • Alt + f / b: move the cursor forward/backward by one word
  • Alt + u / l: turn the word after the cursor upper/lower case
  • Alt + Backspace: delete one word before the cursor
  • Ctrl + x and then Ctrl + u: undo the previous operation

Command history

The shell maintains a list of commands that you have used before. It is saved in an ASCII file ~/.history or ~/.bash_history. You can use less to check the content of it. Pressing Up brings back the previous command. Keep pressing it, you can bring back older commands one by one. If you are a long history list, it take a lot of Up for you to find a command you need. A better way to do it is to do a reverse search of that command in your command history using the key combination Ctrl + r. After that, simply type in any part of the command that you are searching for, bash will bring it back to your prompt. If there is multiple matches of the string that you have typed in, press Ctrl + r again to cycle through them.

Ctrl + s does the search in the opposite direction. However, it is normally hijacked by a program called terminal driver to freeze your terminal. You need to type Ctrl + q to unfreeze it. To avoid this annoying behavior, you can use the following command to tell the terminal driver to let go with Ctrl + s so that it can be used by shell:

$ stty -ixon

You can also put stty -ixon in your ~/.bashrc to make this setting permanent. A few other useful key combinations to deal with the command history are listed below:

  • Alt + <: go to the oldest command
  • Alt + >: go to the newest command
  • Alt + .: bring back the argument of the previous command

Key combinations that control a terminal

In addition to Ctrl + s, the terminal driver also translates some other key combinations into an action. You can use the following command to see a full mapping between the actions and key combinations:

$ stty -a
speed 38400 baud; rows 80; columns 141; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = ^Z; start = ^Q; stop = ^S; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -ixon -ixoff -iuclc ixa

in its output, ^ means Ctrl, capital case letters means small cases (don’t ask me why), so ^C means Ctrl + c. I’d like to emphasize a few useful ones:

  • Ctrl + c: force quitting a hung program
  • Ctrl + d: quit from your shell
  • Ctrl + z: suspend current program, see Job control
  • Ctrl + u: delete everything before your cursor
  • Ctrl + w: delete one word before your cursor

Check system information

$ # things after # is a comment, it won't be executed
$ /sbin/ifconfig # print IP address of the machine you are in
$ uname -a # print operating system information
$ cat /proc/cpuinfo # find out how many CPUs are there in this machine
$ cat /proc/meminfo # find out how big the memory is
$ top # find out who's using the resource, type q to quit
$ df -h # check the disk usage
$ curl wttr.in # show current weather in ASCII arts
$ /sbin/ifconfig | grep inet | head -1 | awk '{print $2}'

This is a combination of many commands used to print out the IP address of the machine nicely. The shell needs to understand which words are commands, how to execute them one by one and how to pass output of one as input to another.