This page last modified: Dec 17 2010
keywords:intro,introduction,linux,tutorial,osx,macos,fedora,ubuntu,unix,command,bash,shell,line,command line, description:Examples of common commands in Linux shells and how to use the command line. title:Linux command line introduction and examples. Table of contents ----------------- Introduction to Unix(TM) (Linux and Mac OSX(TM)) Navigating directories Listing directory contents Copying files Moving and renaming files Viewing files Deleting files Viewing and saving command output Searching inside files Introduction to Unix, Linux, and Mac OSX ----------------------------------------- Modern Linux (conceptually based on Unix) has a graphical desktop just like Windows(TM) and MacOS. Linux even has some themes and skins that make it look and work identical to Windows or Macintosh (the look and feel is user configurable). Mac OSX is a Unix-variant (the Berkeley Standard Distribution or BSD), and is therefore very similar to Linux in most regards. In spite of the graphical desktops, there are still many powerful features only available at the command line. There are all kinds of wonderful and useful tools. The command line is available via a terminal application. Under Linux there are several choices. For many years my favorite was Konsole that comes with the KDE desktop. Lately I've switched over to an old classic called xterm. The Gnome desktop has a terminal also. On the Mac you can use Terminal. If you use an ssh terminal program such as PuTTY or SecureCRT, you will be logging in and working in a command line shell on the Linux server. We will start with an overview of how to enter rudimentary commands and how to navigate at the command line. Then we'll move on to some useful tricks. In this document, the first time a new command or term is used, it will appear surrounded by double quotes. For example, the command line is also known as the "shell". We will assume you are using the "bash" shell, which is the a modern shell, and is the default in Linux and OSX. The first thing you see is a "prompt" which is a string of characters used by the computer to show that is it ready for a command. The computer is waiting for you to type a command. All commands have at least one word, and you must press the enter key to launch the command. There is no harm in pressing the enter key without a command. (In fact many experienced users hit the enter key a few times just to assure themselves that the computer is listening.) Different parts of the command are separated by spaces. Extra spaces are usually ok. Some parts of some commands must occur in a specific order. The "control key" is important in bash. Use it like the shift key. To enter control-c, hold down control and press c. Sometimes control-c is written ctrl-c or ^c or even occasionally (and incorrectly) in upper case Control-C. Bash is almost universally lowercase, and it is case sensitive. Do not use upper case characters unless there is a reason (such as an uppercase character in a file name, or a command switch is uppercase). Bash has all kinds of handy control characters that it recognizes, but ^c is the most important. If you type a command, but change your mind ^c will cancel. If a command is running and hasn't completed (or is going wild) ^c will stop the command (eventually). It is ok to type ^c several times. Bash is stopped with the "exit" command or ^d (control-d). The most common commands fall into broad categories. Your graphical desktop has functions to do the same things as the most common bash commands. The really interesting stuff you can do at the command line is not possible with graphical desktops. We will also use the command syntax description that you'll find in "man pages". Anything in [] is optional. "Switches" are preceded by one hyphen, and switches with long names have double hyphens. Switches enable or disable extra features of the command. You must type the hyphen/double hyphens as necessary. You must not have a space between the hyphen and the text of the switch. When reading man pages, some of the syntax used to describe a command is not literal text, but refers to a variable. Anything variable (like a file name) will be explained in the help for that command. It is sometimes tricky to determine what is literal text and not. Examples should clarify this. The broad categories are below. For historical reasons (and consistency with other documentation) we call "folders" "directories". * navigating directories * listing directory contents * copying files * moving and renaming * deleting * running programs After these fundamental commands, we'll explore powerful and useful commands which give you features that aren't available from a graphical desktop interface. Navigating directories ---------------------- This is done with one command "cd" (change directory). The format is: cd [-L|-P] [dir] Change directory to dir. There are some special directory names: The directory immediately up (parent directory) is .. The current directory is (dot) . You can change several directories down or up by using a longer "path". cd public_html Changes to the public_html directory. cd public_html/images Changes to the images directory in public_html. cd ../../.ssh Changes up two directories into a directory .ssh (yes, the name begins with a dot). Listing directory contents -------------------------- ls [OPTION]... [FILE]... ls (list sorted) has many options, and can take many files as arguments. ls A plain listing of the current directory. ls -l Long listing of the current directory ls -la Long listing, and include "hidden" files with dot at the beginning of their name. ls -l * List everything and also list contents of directories in this directory. ls public_html/images List the files in the images directory in the public_html directory. ls -l public_html/images/*.jpg Only list .jpg files in the images directory. ls -alt List all the files, starting with newest. For more exciting reading see man ls. Copying files ------------- cp [OPTION]... SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION]... --target-directory=DIRECTORY SOURCE... Copy a file from source to destination. Works also to copy a file into a directory. cp is smart enough to know not to overwrite a directory with a file (that's impossible anyway). cp index.html index.html.safe Copy our default home page index.html to index.html.safe. It is ok to have a file with two extensions, however, the web server won't know that a .safe is really a .html file. cp index.html ../ Copy index.html up a directory. cp has funny behavior when copying directories. If you want the directory and all the subdirectories copies, you have to use the -r switch cp -r public_html backup_public_html Moving and renaming files ------------------------- mv [OPTION]... SOURCE DEST mv [OPTION]... SOURCE... DIRECTORY mv [OPTION]... --target-directory=DIRECTORY SOURCE... mv works similar to cp. However, mv will rename directories. mv query.pl query.cgi Rename (move) query.pl to query.cgi mv query.pl /home/mst3k/query.pl Move query.pl to the home directory of mst3k. Unlike what you might expect, you can't use mv to change the extensions of files. mv *.pl *.cgi This won't work. In fact mv will give a message: "mv: when moving multiple files, last argument must be a directory" There is a "rename" utility for wild card renaming. Be careful with rename since is can make a real mess. In fact, it is off topic, but pertinent: before trying any command that may destroy files, it is good to make a backup. The "tar" utility is good for this. Basic use of tar required one command to build a tar archive, and a second command to un-tar the archive. -c is create and -x is extract: tar -cvf tmp.tar *.pl Will create the tar archive tmp.tar from all the .pl files in this directory. tar -xcf tmp.tar will extract all the files in tmp.tar tar -tvf tmp.txt will list all the files in the archive, but not change anything. rename looks like this: rename from to file... "from" is a part of a file name, "to" is what you want the matching part changed to, and "file..." is a file or list of files. To use rename for the mv example above that doesn't work: rename .pl .cgi *.pl Viewing files ------------- This is where the fun starts. Text files are viewed with "more" or "less". Special files like images and word processing are viewed with the usual image editors and word processors, so we won't cover those. It turns out that "less" has more features than "more" which leads to the geeky joke "less is more". more [-dlfpcsu] [-num] [+/ pattern] [+ linenum] [file ...] less -? less --help less -V less --version less [-[+]aBcCdeEfFgGiIJLmMnNqQrRsSuUVwWX~] [-b space] [-h lines] [-j line] [-k keyfile] [-{oO} logfile] [-p pattern] [-P prompt] [-t tag] [-T tagsfile] [-x tab,...] [-y lines] [-[z] lines] [-# shift] [+[+]cmd] [--] [filename]... That's a lot of information. The usual case is just more query.pl less query.pl Both will scroll the file onto the screen, stopping after each screen. Press "space bar" for the next screen. Press "enter" to move down one line. Press "q" to exit. There is one difference between less and more: After it exits, the text more displayed stays on the screen. "less" has all kinds of additional abilities. You can use the cursor keys and page-up/page-down with less. less can also search forward and backward. To search forward, press / (forward slash, below the ?), then enter some text and press enter. Press "n" to find that same text again, and "b" to find previous. less is case sensitive. Enter "-i" and press enter to switch less to case insensitive mode. If less doesn't seem to be in command mode use ^c or ":" the colon. less will not be killed by ^c, so you'll have to exit with q. more only works on text files. less will display binary files, and in my experience won't mess up your terminal settings (like might happen with "cat" on a binary file). You can also display files with the text editors vi (vim) and emacs. Both of those utilities are complex enough to deserve their own documentation. In modern version of both you can probably scroll around with the arrow keys and page-up/page-down. Exit from emacs with ^x^c and exit from vi by entering command mode with Esc "escape" or ":" and quit with q. Deleting files -------------- Deleting files is dangerous in Linux and BSD because it's creators have not seen fit to allow undelete or to implement a trash can. This is just one of many cases of snobbery amongst Linux and BSD people. They have all kinds of justifications, and they clearly aren't about to change, so we'll have to work around the problem. Perhaps the safest thing is to simply mv files to your favorite trash folder. mv query.pl ~/Desktop/Trash move query.pl to Desktop/Trash in my home directory. ~/ is short hand for "my home directory". When you want to get rid of a file, use rm. rm query.pl Remove query.pl Often the "rm" command has been aliased to "rm -i" which is "interactive" which means it asks before doing anything. Answer with y and enter to delete the file or n and enter (or just enter) to keep the file. [mst3k@tull ~]$ rm -i query.pl rm: remove regular file `query.pl'? y [mst3k@tull ~]$ The most dangerous command is "rm -fr *" which is rm force, recurse all files. "force" is don't ask, "recurse" is go into all subdirectories. This command can delete every file you own. If you are logged in as root, you can delete ever file on the disk. If you want to use rm -fr, follow these steps for safety (and maybe make a tar file first). We'll clean up everything in the "mars" directory. The commands below will: cd into mars, check that we really are in the mars directory (pwd is "print working directory"), ls the directory to make sure it really has the files we think it has, then use a variation of rm -fr that deletes files starting in this directory, and at last we ls and that everything is gone. ls -l might have been a better command. You can't tell here, but "sol62_fr" and "front_right" are both directories with files in them. All those files were deleted. [mst3k@tull ~]$ cd mars [mst3k@tull mars]$ [mst3k@tull mars]$ pwd /home/mst3k/mars [mst3k@tull mars]$ ls 2R131787621EFF1200P1310R0M1-BR.JPG 2R131962287EFF1400P1310R0M1-BR.JPG sol62_fr 2R131871671EFF1300P1310R0M1-BR.JPG front_right [mst3k@tull mars]$ rm -fr ./* [mst3k@tull mars]$ ls [mst3k@tull mars]$ Running programs ---------------- By this point in the tutorial you have been running programs. Most commands are simply programs. There are hundreds of them, but only a few dozen are commonly used. If you try to run a command that does not exist, you'll get an error message: [mst3k@tull ~]$ argle bash: argle: command not found [mst3k@tull ~]$ If you run a command that fails, you will also get an error message: [mst3k@tull ~]$ cd argle bash: cd: argle: No such file or directory [mst3k@tull ~]$ The bash shell has "tab completion" which is a wonderful feature. It is so wonderful that people like myself can't imagine using a graphical interface where tab complete doesn't exist. Press tab once to complete a command, file name, or directory name. If the name does not complete, press tab a second time to get a list of possible completions. In the example below I'm looking for a ls command, but I can't remember the name. I type "ls" then hit tab twice: [mst3k@tull ~]$ ls ls lsbom lsdistcc lshal lsm lsof lsvfs [mst3k@tull ~]$ ls Tab complete is very handy for entering long directory paths and file names. Type part, hit tab, type a little more, hit tab again. It becomes easy to tab-complete to enter a path such as /Users/mst3k/Library/FontCollections/Modern.collection It is an interactive process. Occasionally you'll get a message such as: Display all 1086 possibilities? (y or n) Displaying that can take several screens. The list will be sorted. You might want to enter "n" and then enter one or two more letters before tabbing. [mst3k@tull ~]$ less /usr/bin/ Display all 1086 possibilities? (y or n) n [mst3k@tull ~]$ less /usr/bin/p Display all 137 possibilities? (y or n) n [mst3k@tull ~]$ less /usr/bin/pr pr priclass.d printenv procmail profiles prove prove5.8.9 pre-grohtml pridist.d printf procsystime projectInfo prove5.10.0 [mst3k@tull ~]$ less /usr/bin/pr Viewing and saving command output --------------------------------- If you want to ls -l a very large number of files, the list will scroll off the screen. Shell commands can be "piped" together. The output of one command is the input of another. In general this falls into the categories of "piping output" and "i/o redirection" (sometimes spelled "io") for input/output. Pipes use the pipe character "|" which is shift "\" (backslash) on most keyboards, and above the enter key. ls -l | less A long list all files piped to less. Now you can scroll up and down the list with less, and even search. You could send the list to a file with i/o redirection. ls -l > ls_out.txt less ls_out.txt Make a long listing, send it to the file ls_out.txt, then less the file. Capturing output is very handy when it will take a long time to run a command. For instance, getting a list of packages that yum can install might take a minute or two. I prefer to save the listing to a file and search the listing with less or grep. yum list all > yum_list.txt The > will take output and redirect it to a file. The file is overwritten, which means that the contents of the file are destroyed. There is no undo. You often want to overwrite temporary files. However, if you have something like a log file, you probably want to append output (concatenate). Use the >> redirection. ls -alt ./documentation/* >> big_list.txt ls -alt ./spreadsheets/* >> big_list.txt Make a date sorted long list of all files, and append it to the end of big_list.txt. In the example below we overwrite big_list.txt with > and then append with >> ls -alt ./new_files/* > big_list.txt ls -alt /home/mst3k/* >> big_list.txt Searching inside files ---------------------- The utility "grep" (get regular expression and print) will search for regular expression matches inside files. grep has many uses, and we'll only cover a few more common examples. Regular expressions are a way of describing simple or complex wild card text matches. However, the regex * is not a wild card. Instead "." (dot) matches any single character. Perhaps the best way to use grep (at least on Linux) is to rely on simple regex's and if you need something complex, use the Perl regex switch "-P" and read Perl's perlre man page "man perlre". I don't think BSD is using the GNU grep, so they probably don't have Perl regex's available. grep tcp /etc/services Will search /etc/services for "tcp", and print every line that matches. ls /etc/ | grep serv Will list all the files in /etc, pipe the list to grep, and grep will search that list for matches to "serv". The output of grep can be long. You can find out which files contain some text, but you'll have to pipe the list through less grep tcp /etc/s* | less Will grep /etc/s* (which is a lot of files) looking for "tcp". Some files you can't read, and so a few permission messages will print. That's ok. Use the -c to get a count of matches in each file. grep -c tcp /etc/s* | less This prints lines like /etc/sensors.conf:0 /etc/services:262 /etc/sestatus.conf:0 We really are only interested in files that don't have zero matches, so we can use the -v switch to get lines which did not match (reversed logic). grep -c tcp /etc/s* | grep -v :0 Search for matches against "tcp" and pipe that list to grep and search for lines that did not match ":0". Below is a transcript. [mst3k@tull ~]$ grep -c tcp /etc/s* | grep -v :0 grep: /etc/securetty: Permission denied grep: /etc/shadow: Permission denied grep: /etc/shadow-: Permission denied grep: /etc/sudoers: Permission denied /etc/services:262 [mst3k@tull ~]$ It is common to use grep, ls as well as "wc" and "find". find is complicated and deserves its own chapter. wc is "word count" is will count bytes, words, and lines. ls *.pl | wc -l List all the Perl scripts and count them (by counting the lines in the output). Here is an example using the Perl extended regexps in grep. The regexp "\d+" means "match digits where there is at least 1 digit". ls | grep -P "\d+" | less There are a few oddities at the command line. It can be tricky to list files with a leading dot (called "dot files") without listing other files. Deleting dot files require a trick or two. Dealing with files that have strange characters (including spaces) in the file names also requires special tricks. "Quoting" also known as "escaping" can be helpful. The command below escapes a space so that I can list all files that have a space in the name. Interestingly, the file is a symbolic link to a longer file name in another directory. [mst3k@tull ~]$ ls -l *\ * lrwxr-xr-x 1 mst3k mst3k 65 Apr 2 10:17 Archivists' Toolkit 2.0 -> /Applications/Archivists' Toolkit 2.0/Archivists' Toolkit 2.0.app [mst3k@tull ~]$