\chapter{Basic Terminal Commands} A lot of people are reluctant to try Linux because they think you need to be proficient in the terminal, which is not true. The point of Linux, after all, is that it is a GUI (a graphical user interface) which is meant to eliminate your need to use text-based commands. The fact is, you don't need to use the terminal at all to use Linux. But your life in Linux can get a lot easier if you do use the terminal. It can also get a lot of harder if you use the terminal improperly. What follows is a basic introduction to using the terminal. It's designed to get your feet wet, not to make you an expert user. \section{What is a Terminal?} We really should talk about what a terminal actually is, though, because Linux doesn't actually have one. What Linux has is a terminal \textit{emulator}. Now we have two questions: what is a terminal and what is a terminal emulator? In the early days of computing, computers were huge and often took up the entire basement of a building. The only way to input data into them was to use punched cards\footnote{See \kref{https://en.wikipedia.org/wiki/Punched_card}{https://en.wikipedia.org/wiki/Punched\_card}} or paper tape\footnote{See \kref{https://en.wikipedia.org/wiki/Punched_tape}{https://en.wikipedia.org/wiki/Punched\_tape}} which meant that to interact with the computer, you had to prepare your cards or your tape and then head down to the basement.\footnote{For attribution and licensing information for the images in this chapter, see \kref{https://en.wikipedia.org/wiki/File:Used_Punchcard_(5151286161).jpg}{https://en.wikipedia.org/wiki/File:Used\_Punchcard\_(5151286161).jpg}, \kref{https://en.wikipedia.org/wiki/File:PaperTapes-5and8Hole.jpg}{https://e\\n.wikipedia.org/wiki/File:PaperTapes-5and8Hole.jpg}, and \kref{https://en.wikipedia.org/wiki/File:DEC_VT100_terminal_transparent.png}{https://en.wikipedia.o\\rg/wiki/File:DEC\_VT100\_terminal\_transparent.png}.} Somebody eventually figured out a way to use a keyboard to provide input for a computer, which meant that you could put the keyboard in your office on the third floor and just run wires from it down to the computer. No more running up and down the stairs with paper cards or tape in your hands. The output from the terminal originally went to a line printer, but at some point, somebody realized that they could use a CRT (a cathode-ray tube, aking to what televisions used to be before flat screens came along) and send the output to that, instead, thus saving on paper. Pretty handy. \begin{wrapfigure}[10]{r}{0.4\textwidth} \includegraphics[scale=0.9]{punch_card} \caption{A 12-row/80-column IBM punch card from the mid-twentieth century} \end{wrapfigure} The point here is that a terminal is a physical object (either keyboard and printer or keyboard and screen), while the terminal emulator in Linux is merely a piece of software that allows you to interact with the Linux kernel (i.e., that bit of software that exists between the physical hardware of the computer and the programs you use on a regular day). Thus, the Linux terminal just \textit{emulates} that keyboard and monitor, hence it's a terminal \textit{emulator}, rather than an actual terminal. But by and large, people don't bother to make that distinction any more (and I'm willing to be a lot of people don't even know that distinction exists) and when people talk about a modern day terminal, they're really talking about a terminal emulator. \begin{wrapfigure}[9]{l}{0.4\textwidth} \includegraphics[scale=0.9]{paper_tape} \caption{Five- and eight-hole punched paper tape} \end{wrapfigure} By far, one of the most popular (not to mention the earliest) terminals in Linux is \textsf{Bash}—the Bourne Again SHell. The actual Bourne shell was developed by Stephen Bourne at Bell Lab in 1979 for use on Unix. Bash was created by Brian Fox for the GNU project in 1989 as a free software alternative to the Bourne shell—same functions, different code base. \begin{wrapfigure}[11]{r}{0.4\textwidth} \includegraphics[scale=0.95]{dec_vt100} \caption{The DEC VT100, a widely emulated computer terminal} \end{wrapfigure} Over to the right, we see a DEC terminal, which is similar to the terminal I used when I was in college the first time around. I wrote about this way back in the third issue of this zine, which seems like a lifetime ago, but was really only two and a half years ago. Gosh, how times flies when you and the rest of the world is in the middle of an existential crisis. It occurs to me that I am a member of an increasingly smaller and smaller group: people who used an actual terminal to do stuff. Of course, at the time ``doing stuff'' basically meant just typing up my notes from class. My background in computers was basically programming in BASIC, and I had no idea how to do much else. But I had terrible handwriting, and I wanted a decent copy of my class notes to refer to, so it was either check out a typewriter room on the first floor of the dorm or the second floor of the library\footnote{In those days, you could check out a study room either with or without a typewriter. What an eternity ago that seems like now.} or use the computer. Using the computer meant that I didn't have to bother with correction paper—I could just edit on the terminal. I would save my files, then send them to the printer in another room, then go stand in line to get my printouts. It was a different age, to be certain. \section{Basic Commands} Enough about me. Let's talk about some basic terminal commands you can start using right now. But first, let's talk about information, and which way it flows… \section{Input, Output, Errors, Redirects, and Piping} Every command has three things you need to consider: what input you provide the command, what output the command gives you, and what kinds of errors (hopefully none) you encounter. We have standard names for these things: \texttt{stdin}, \texttt{stdout}, and \texttt{stderr}, because these things are, well…\textit{standard}. We refer to these things as ``standard streams'' because again, they are standard with every command you give, and they are also a stream—meaning a flow of information.\footnote{See \kref{https://en.wikipedia.org/wiki/Standard_streams}{https://en.wikipedia.org/wiki/Standard\_streams} for a bit more information.} It's important to understand what these things are, because you are going to encounter them in online discussions about terminal commands, and as will all things, understanding these things makes your life easier. For example, let's say that you want to see the contents of a particular directory. You would use the command \texttt{ls} (which we will talk about in a bit), and the \texttt{stdin} you would provide would be the name of the directoy. The \texttt{stdout} would be the contents of that directory. If you misspelled the name of the directory or the directory doesn't exist, then the \texttt{ls} command would give you an error like ``cannot access : No such file or directory'', which would be the \texttt{stderr}. It's important to understand standard streams because you need to understand exactly what a command needs to get from you in order to operate correctly, and you also need to understand where it is sending its \texttt{stdout} and \texttt{stderr} in case you get something you weren't expecting. For the most part, simple commands send their \texttt{stdout} and \texttt{stderr} to your monitor. (If this were 1972, those would probably go to that line printer attached to your terminal.) But it's also possible to \textit{redirect} those streams to a file, via a redirect symbol (which is typically >). This is sometimes handy if you want a record of that information, or you need to use that data in a different program like a spreadsheet. It's also possible to take the \texttt{stdout} of one command and use it as the \texttt{stdin} of another command. This is called ``piping'' and makes use of the pipe symbol (that is, |) that is generally located on the key just above the \kkey{enter} key on your keyboard. This is a good technique when you know the command you are using will produce a lot of output, but you are only concerned with a small subset of it, so you send that output through a command (usually \texttt{grep}, which we will talk about) to filter out just the bits that you are interested in. We'll look at specifics about redirects and piping when we discuss actual commands. \subsection{Accessing the Terminal} You have two ways to access the terminal on most Linux systems.\footnote{For the record, I am most familiar with Ubuntu, which is based on Debian, but not all Linux distros work exactly the same way. Going forward, whenever I make a statement, assume that I mean ``on most Linux systems, and in particular, Debian-based systems like Ubuntu''.} First, you can go into your application manager and search for ``terminal''. You can install other terminals besides Bash, so if you type that command, you'll probably see them. The other, easier (and thus the method I use) is to hit \kkey{ctrl-alt-t} on your keyboard, which will open up your default terminal. \subsection{The Basics} Now that you have your terminal open, let's try some basic commands. The first one we'll try is \texttt{pwd} which is short for ``print working directory''. It's only job is to tell you which directory you're in. Generally, your terminal opens up in your user home directory, so using that command reveals the path to that directory from the root directory which in my case looks like \begin{Verbatim}[] /home/kjodle \end{Verbatim} This may not seem like a useful command, but if you start wandering around in the guts of your filesystem, it's easy to forget where you are, and then this command is \textit{very} handy. If you forget who you are, you can also use the \texttt{whoami} command, which simply returns your user name. Again, this may not seem very useful, but sometimes you have to log in as the root user, and if you forget whether you're logged in as the root user or a regular user, this becomes not handy but absolutely necessary. (You can wreak havoc on your system quite easily when logged in as root, so this is a good thing to check.) If you are logged in as the root user, \texttt{whoami} should return ``root'' rather than your regular user name. \subsection{Moving Around} Now that you know who and where you are, you probably want to move around a bit. The command to change directories is \texttt{cd} (which stands for ``change directory''—sometimes these things make sense). If you are in your home directory and you want to change to your Documents directory, you would use: \begin{Verbatim}[] cd Documents \end{Verbatim} Notice that it is ``Documents'' and not ``documents''. Case matters a lot in Linux. If you are typing a command and you are sure that you have the syntax correct but it is not working, check the lettercase. It's possible you're typing something in lower case when the actual target is written in upper case. Once you're in that directory, the \texttt{pwd} command should give you this output: \begin{Verbatim}[] /home//Documents \end{Verbatim} To get back to my user directory, I would them type: \begin{Verbatim}[] cd .. \end{Verbatim} The two dots mean ``go up one directory''. If I wanted to go up two directories, I would use: \begin{Verbatim}[] cd ../.. \end{Verbatim} Which means ``go up one directory (the first two dots) and then go up one more (the forward slash and the second two dots)''. And to go down two or more directories, we would use the forward slash again: \begin{Verbatim}[] cd /Documents/"super secret stuff" \end{Verbatim} Notice that the folder ``super secret stuff'' has spaces in the title. Bash will recognize a space as marking the next option, so if we used that command without quotation marks Bash would give us an error saying there are too many arguments or that it doesn't understand the option ``secret''. This is one reason to avoid naming files or directories with spaces and why a lot of people use underscores instead of spaces. \subsection{Seeing What's There} Once you're in a directory, you probably want to see what's there. The command for that is \texttt{ls}. If you have a lot of files or subdirectories, the \texttt{ls} command isn't all that useful, because it just gives you everything that is in there, but it doesn't tell you much about the contents. Fortunately, \texttt{ls} has tons of options. My favorites are \texttt{-a} which displays invisible files and directories, \texttt{-h} which displays file and directoy sizes in human readable forms (in other words, you get ``16k'' instead of 16176, which is in bytes), and \texttt{-l} which means to give a long display. And yes, you can combine these options: For example, if I run \texttt{ls -ahl} in my ``Documents'' directory, I get this output: \begin{small} \begin{Verbatim}[frame=lines, numbers=left, xleftmargin=5mm, framesep=3mm, breaklines=true, label=\fbox{Output of 'ls -ahl' in Documents directory}] drwxrwxr-x 2 kjodle kjodle 4.0K Mar 6 2021 'About Me' drwxrwxrwx 5 kjodle kjodle 4.0K Aug 5 2023 'Audio Recordings' -rwxrwxr-x 1 kjodle kjodle 1.5K Jan 3 15:08 backup.sh drwxrwxr-x 2 kjodle kjodle 4.0K Nov 27 17:03 Bookmarks -rw-rw-r-- 1 kjodle kjodle 4.1K Jun 30 2024 bookmarks.xml drwxrwxrwx 15 kjodle kjodle 4.0K Oct 6 07:51 Business drwxrwxrwx 3 kjodle kjodle 4.0K Mar 30 2019 'Business Cards' drwxrwxr-x 4 kjodle kjodle 4.0K Jul 29 2022 calibre drwxrwxrwx 8 kjodle kjodle 4.0K Mar 6 2018 'Calibre Projects' drwxrwxrwx 3 kjodle kjodle 4.0K Jul 5 2020 Collections drwxrwxr-x 16 kjodle kjodle 4.0K Aug 13 2023 Correspondence *snip* \end{Verbatim} \end{small} That seems like a lot of information, but it's highly useful information. To sum it up: \begin{itemize}[noitemsep] \item The first column (starting with either ``dr'' or ``-r'') shows the permisions on the file or directory. Items that start with a ``d`` are directories, and items that start with ``-'' are files. \item The second column shows the number of hardlinks to that item. This is really beyond the scope of this tutorial, but for directories, you can think of it as the number of items that directory contains.\footnote{See \kref{https://linuxgazette.net/issue35/tag/links.html}{https://linuxgazette.net/issue35/tag/links.html} and \kref{https://linuxgazette.net/issue93/tag/2.html}{https://linuxgaze\\tte.net/issue93/tag/2.html} for more information.} \item The third column shows the owner and the fourth column shows the group. This is also related to permissions. \item The fifth column shows the size, in human-readable form (because we used the \texttt{-h} option). Notice that directories show up as `4.0 k' which is also beyond the scope of this tutorial, but is related to the second column, so take a look at those footnotes to better understand this. \item The fifth column is either the creation date or the last modified date. \item The sixth and final column is the name. Again, notice that Linux puts single quotation marks around any names that contain a space. \end{itemize} As I mentioned earlier, you can also redirect the \texttt{stdout} of this command to a file. For example, this command: \input{include/ls_redirect} will create a file called ``documents.txt'' that contains a list of everything (except for invisible files and directories) in your ``Documents'' folder. \subsection{Finding Things} The Linux filesystem is large, and chances are that your home directory is also large and complex. It's easy to lose things. Fortunately, Linux has a number of commands to help you find things. The simplest of these is \texttt{locate}. All you have to do is provide a search term and \texttt{locate} will search your entire filesystem for any item that contains that search term. \texttt{locate} is a fairly blunt instrument, however. Unless the search term you provide to it is extremely specific, it will return a \textit{very} long list of results. To get some idea of how many results you will get, you can pass the count option (\texttt{-c}) to it. Using ``latex'' as a search term with the count option returns ``122132'' which means that there are just around an eighth of a million items on my filesystem with ``latex'' in the name. A more useful command is \texttt{find}, which has a \textit{ton} of options. (The \texttt{man} page runs to over 1,600 lines, so yep, a lot of options.) A command like \texttt{find } will search your entire filesystem for directories and files containing \texttt{} in their name. To search just your home directory, you can use \texttt{find \$HOME }. \subsection{Finding Binaries} A \textit{binary} is just another name for an application file that you can run. Often you need to find where a binary is located so that you can add it as a command to another application. You have a couple of options here. \paragraph{which} This command will return the name of all binaries that are located in your \texttt{PATH} variable, which is a list of locations that your system will search when attempting to execute that command. For example, if I run \texttt{which latex} in a terminal, I get this output \texttt{/usr/bin/latex}. This tells me a couple of things. First, it means that LaTeX is installed on my system. Second, it tells me that its location is contained in my \texttt{PATH} variable, which means that I can use it by simply typing \texttt{latex} in a terminal. \paragraph{whereis} Sometimes binaries get installed without getting added to the \texttt{PATH}, however. To find all binaries, regardless of whether or not they are in the \texttt{PATH}, use \texttt{wheris}. For example, typing \texttt{whereis latex} in my terminal gives me this output: \begin{Verbatim}[] latex: /usr/bin/latex /usr/share/man/man1/latex.1.gz \end{Verbatim} The first item is the location of the binary, while the second one is the location of the \texttt{man} (i.e., the ``manual'') page for this application. \subsection{Wildcards} The \texttt{find} command is useful because it can take wildcards. A full discussion of wildcards is beyond the scope of this tutorial, because we are edging into regex (short for ``regular expressions'') territory. But lets take a look at the simpler ones. The first is \texttt{?} which takes the place of a single character. Thus \texttt{find ?at} would match ``cat'' and ''hat'' but it wouldn't match ``what''. There is also \texttt{*} which matches any character of any length. The command \texttt{find *at} would match ``cat'', ``hat'', ``what'', and also ``casey\_at\_the\_\-bat''. You can also use square brackets to provide a comma-delimited list of characters to match. The command \texttt{find [b,c]at} would match both ``bat'' and ``cat'' but it wouldn't match ``hat''. Of course, you can combine these. \texttt{find *[b,c]at} would match ``bat'' and ``cat'' and ``casey\_at\_the\_bat'' but not ``hat''. These are the most basic examples of wildcard usage, but they have sufficed for 99\% of the searches I've done over the years, if not more. I will talk about regex in a later issue, though, because it is one of the most useful skills to have. \subsection{grep} \subsection{Working with Files and Directories} Bash has a number of commands for working with files and directories. The first is \texttt{touch} which will create a file if it doesn't exist, or will update the date and time it was modified if it does exist.\footnote{I admit, I'm a little confused as to the purpose of this command, and have never found a use for it. It is probably a legacy from the early days of Linux or possbily Unix, and I have never had the time—or the amount of curiosity required—to investigate it.} \paragraph{cat} A command I do find a lot of use for however is \texttt{cat}, which is short for ``concatenate''. This command can also create files and add content to them, but it can also add content to existing files. But the thing I find it most useful for is simply displaying the contents of a file, which I use a lot when examining log files. However, \texttt{cat} can also be used to create files. If you type \texttt{cat > } in the terminal, it will create a file named ``'' and then go into \textit{interactive mode}, meaning it looks like it's not doing anything. In reality, it's waiting for you to add input. Type what you want the contents of the file to be and then press \kkey{ctrl+d} to save the file and exit interactive mode. Notice that we are using a redirect symbol here (\texttt{>}) to push your content to that file. If you repeat this command with different text, \texttt{cat} will just overwrite what you initially wrote. To append text to a file, rather than overwrite it, use \texttt{>}\texttt{>}. \paragraph{head} \paragraph{tail} \paragraph{more} \paragraph{mkdir} To make a directory you can use the \texttt{mkdir} command, which is pretty straightforward. You can also create subdirectories by specifying the path to the subdirectory you want to create. For example, \texttt{mkdir 1/2/3} will create a directory named ``3'' in that path, provided that directories 1 and 2 exist in the first place. If they don't, \texttt{mkdir} will return an error. \paragraph{cp} If you want to make a copy of a file, use the \texttt{cp} command. Its syntax is pretty straightfoward: just specify the file you want to copy and then specify the name of the copied file. You can also use paths as well, so \texttt{cp 1/2/a.txt 3/4/b.txt} will go to directory ``1'' and then to directory ``2'' and copy the file ``a.txt'' to directory ``4'' located in directory ``3'' and rename it as ``b.txt''. Again, all those directories must exist in the first place, or \texttt{cp} will return an error. \paragraph{mv} To move a file, use the \texttt{mv} command. Just specify the name of the file you want to move, and then the path you want to move it to. Interestingly, Linux does not have a command for renaming a file, but you can use the \texttt{mv} command to rename a file by not specifying a new path. Take a look at the following examples: \begin{Verbatim}[frame=lines, numbers=left, xleftmargin=5mm, framesep=3mm, breaklines=true, label=\fbox{Examples of the mv Command}] mv cat.txt bat.txt mv cat.txt animals/mammals mv cat.txt animals/mammals/bat.txt \end{Verbatim} The command in line 1 simply renames the file ``cat.txt'' to ``bat.txt'' and leaves it in the same directory. The command in line 2 moves the file ``cat.txt'' to the subdirectory ``mammals'' which is located in the subdirectory ``animals'' which itself is a subdirectory of the current directoy. The third command is a combination of the first two: it both moves the ``cat.txt'' file and also renames it as ``bat.txt''. \paragraph{rmdir} \section{Two More Important Things} If your terminal window gets filled with text and you find that distracting (which my ADHD brain often does), just use the command \texttt{clear} to get an empty window. Also, if you type a command and it starts giving you \textit{tons} of output and you realize that you've done something wrong, you can usually make it exit by typing \kkey{ctrl+d}. Depending on what command you executed, there may or may not be any damage done.