Notation: The examples below illustrate what to type on a command line.
It is a common convention to begin lines with $
to indicate the command
prompt. Lines that do not begin with $
show the expected output
from executing the command. Thus, you do not type the $
or
anything on a line without a $
at the beginning.
Common shell commands
In order to compile your projects on stu
, you need to know some basics
of how to work on the Linux command-line.
Command |
Description |
Example |
cd |
Changes directories. You can either use an
absolute path (e.g., cd /usr/bin ) or a
relative path (e.g., cd bin ). |
$ cd cs361-p1/tests |
ls |
List files. If you want to see details (such as file
size), you can do ls -l . If you are looking for files that
match a particular pattern, you can use * as a wild card. |
$ ls -ltr *.c ... |
pwd |
Prints the current directory. This is a good utility if
you're not sure what directory you're in. |
$ pwd /cs/home/stu/lennonjw |
which |
Perform a PATH lookup for an executable program or shell
built-in. This is a good way to determine if you are running the correct
program. |
$ which ls /bin/ls |
mkdir |
Create a new subdirectory. |
$ mkdir cs361-p1/src/printer |
cat |
Print out the contents of a file. |
$ cat tests/Makefile |
mv |
Rename a file or move it to another directory. |
$ mv src/main.c src/project.c |
rm |
Delete (remove) a file. If you want to delete a
directory, you need to use rmdir (if the directory is
empty) or rm -rf (if it is not) Warning: There is
no undo . Once you delete it, it is gone. |
$ rm -rf build |
make |
The command we will be using to compile code. This
command assumes there is a file called Makefile in the current
directory. More on this later. |
$ make verbose.test |
gcc |
The actual command to invoke the GNU C compiler. If
your code is C++, you should use g++ instead. (The two
work more or less identically.) |
$ gcc -c input.c -o input.o |
tar |
Create or extract the contents of a tar archive.
Use the -c flag to create one or the -x flag to
extract. You can also use -t to list a table of contents. |
$ tar cvfz cs361-p1.tgz cs361-p1 |
gzip |
A compression program. Tar files are generally
compressed with gzip . Use gunzip to de-compress it.
There is a similar pair of programs (bzip2 and bunzip2 )
that give you better compression (i.e., a smaller file), but they
take significantly longer to run. |
$ gunzip cs361-p1.tgz |
man |
Displays the help manual for a command. Press q
to quit, spacebar to move to the next page, or h for help
(explains more options). |
$ man gzip |
git |
Command for all Git revision control operations. You will use this to
submit your code. |
$ git add . |
hg |
Command for all Mercurial operations. You will use
to submit your code. |
$ hg help
$ hg add |
hexdump |
Print the contents of a file in hexadecimal format.
Very useful for working with binary files. |
$ hexdump add.o
0000000: 01 00 00 01 10 00 02 00 |
grep |
Great tool for pattern matching. Finds locations
of text in a file. |
$ grep stdi file.c
#include <stdio.h> |
tee |
Writes output to both a file and the screen concurrently. |
$ echo hello | tee output.txt hello |
env |
List current environment variables or run command with custom environment.
The -i flag clears all environment variables except for those passed. |
$ env -i PATH= ls env: ls: No such file or directory |
echo |
Prints out a message to the screen. This is particularly good for working
with variables. One really important environment variable is $? ,
which is the return code of the previous command. |
$ ls asldkfj ls: asldkfj: No such file or directory $ echo $? 1 |
export |
Add a new environment variable key-value pair. Variables are accessed with
a dollar sign before the name, possibly with curly braces (e.g., $DEBUG
or ${DEBUG} ). Environment variables can be accessed by processes
running C programs with the getenv() function (e.g.,
char *debug = getenv ("DEBUG"); ). If you set a variable without
export (e.g., just do DEBUG=true at the prompt), the variable
can be accessed by the shell (echo $DEBUG ), but it is not passed as
an environment variable to processes. |
$ export DEBUG=true $ echo $DEBUG true $ n=42 $ echo $n 42 |
unset |
Clears an environment variable that has been exported. |
$ unset DEBUG |
cut |
Splits STDIN text based on a delimeter (-d ). You can
select a particular field number (-f ), as if the split string is
an array (indexed from 1 instead of 0). |
$ echo "a/b/c" | cut -d'/' -f2 b |
awk |
A full and complicated programming language, but there is one very helpful
trick: print selected columns from whitespace-separated text. Use $1
to refer to the first column, $2 for the second, etc. $NF
gets the last column. |
$ echo a b c | awk '{print $1" "$NF}' a c |
In addition, the following pieces of information are helpful:
$HOME
or ~
refer to your home directory
When you first pull up a terminal or ssh
to a machine (such as
stu
, you are placed on your $HOME
directory, which is
for your account. So $HOME/cs361-p1
and ~/cs361-p1
both
mean the same thing: they are referring to the cs361-p1
subdirectory of your account.
- Current directory is
.
and parent is ..
If you want to refer to a file (or directory) relative to your current
working directory (i.e., the place you used cd
to get
to), you can use ./that_file
. The ..
refers to the
directory up one level. For example:
$ ./build/program [run "program" found in the build subdirectory]
$ cd build
$ ./program ["program" is now in the current directory]
$ pwd
/cs/home/stu/lennonjw/p1/cs361-p1/build
$ cd ../.. [go up two directory levels]
$ pwd
/cs/home/stu/lennonjw/p1
- Hit
tab
for automcomplete.
This will save you time when typing. It also serves as an error check. If
you make a typo and hit tab
, you'll hear a beeping noise. This
either means (a) there are multiple file names that match or (b) no file
name matches. To tell which it is, hit tab
again. If there are
multiple files, you'll see a list of the possibilities. Otherwise, you'll
see nothing.This is a good way to make sure you don't misspell
directory names.
- Learn a command-line text editor.
There are text editors listed below that are nice to use for your
personal computer. You can't use any of them on stu
. As
such, there really is no replacement for learning vim
or emacs
.
- Use
-h
or --help
as a first resort
Every command has built-in documentation that you can get to by passing
these flags. (Some don't have the --help
option.) If you're not
sure what a command does, you should go with this option first. This is
how you avoid getting told to RTFM
(apologies for the vulgarity and I will never tell you
this, but it's common Internet slang that you may encounter).
- Use pipes (
|
) to string commands together
The pipe will taken everything that one command prints to stdout
and redirect it as input to the next command's stdin
. You won't
see the first command's output unless the second one repeats it. These
can be chained together as much as you want:
$ find . | grep \.c$ | sort
src/cmdline/parse.c
src/main/main.c
src/y86/elf.c
- Learn pattern matching and regular expressions.
The star (*
) can be used as a wild-card when listing files. For
instance, ls src/*/*.c
will match all three of the .c
files above. Commands like grep
use special patterns called
regular expressions. As a quick intro, $
means "end of the
line of text," ^
means "beginning of the line," and .
means "match any character." You can use \
to escape any of
these special meanings.
Learning the Linux command line takes a lot of time and practice. If you want
more information, you should search for something like "Linux command line
tutorial." You'll find plenty of resources online.
Remote command-line access
To do anything on stu
, you first need to actually connect to the
machine. This is done using SSH. A popular GUI-based program for using SSH is
PuTTY.
Or, if you have a local command line, you can just use the following command:
$ ssh yourusername@stu.cs.jmu.edu
While you're at it, if you want to make your life easier, you can set up your
system to login to stu
automatically without having to enter your
password. See this tutorial
to learn how.
Text files on stu
Lastly, you may often want to see the contents of your files while on
stu
. If you just want to print out the whole thing, you can execute:
$ cat src/main/main.c
#include <stdio.h> /* standard I/O */
#include "../cmdline/parse.h" /* command line parser */
#include "../y86/elf.h" /* Mini-ELF format */
int
main (int argc, char **argv)
{
printf ("Congratulations, you have compiled your source code!\n");
return 0;
}
If you want to edit the file, you need a text editor. Using vim
or emacs
is preferred.
A simple approach would be to use nano
:
The bottom of the screen shows you the commands for nano
For instance,
to exit, you hit ^x
(Ctrl-x
). The option for saving is called
WriteOut
.
Environment configuration
In your account on stu
, there is a file called $HOME/.bashrc
(note that the name starts with a dot "."). You can use this to create various
command-line shortcuts that will make your life easier. One of them is to create
an environment variable that stores common strings that you'll get very
sick and tired of typing. (Note that $HOME
is an environment variable
that is set by default.)
Open your $HOME/.bashrc
in a text editor, then go to the bottom of
the file. You can then add the following line to refer to the common course location:
export CS361=/cs/students/cs361/s25/kirkpams
After you save the file, log out from stu
and log back in again.
You'll then be able to use a new $CS361
environment variable in
commands you type. For instance, to navigate to the course's source code directory,
you can type the following:
Local command-line access
To get better at working with the Linux command line, you may consider setting
up your Windows or Mac machine to give you a similar environment. On Windows,
you can use Cygwin, which gives you a
Linux-like command line for Windows, including standard Linux tools (including
command-line programs you can use to compile C/C++ code). You can also use
MinGW, which provides a very minimal setup
that will let you compile and run code. If you have a Mac, you already have a
command line. Go to Applications -> Utilities -> Terminal
to
bring up the terminal command line. For a full Linux-like experience, you can
install MacPorts or
Homebrew (recommended).
Text editors
To write code, you just need a program that can edit plain text files. You
definitely should not, under any circumstances, use any
WYSIWYG program, such as
Word, Notepad, or Pages (Mac). These programs add formatting information to
the file, and that formatting information gets treated by the compiler as if
it were part of your code. The following are good (and free!) text editors that
are commonly used by programmers:
Note that Eclipse is a full-featured integrated development environment (IDE),
and is much more complex than any of the others. Lastly, if you are on the
command line, you can use vim
, emacs
, or nano
to edit
a file, but all of those require learning special command keys. Google the name
of the program to find many, many tutorials on each.
File transfers
Perhaps the easiest way to get started with C development for this class is
to write your code on your own machine (e.g., a laptop), then transfer
your files over manually. There are many techniques for doing this. For a
GUI-based approach, you might consider installing and using one of these
programs:
Alternatively, if you have a local command line (see next section), you can use
scp to copy files over
to stu
.
Extract archive contents
When you use tar
to extract (x
) from a gzipped (z
)
file (f
) in verbose format (v
), you'll see a list of the files
as they are extracted:
$ tar xvfz cs361-p1.tgz
cs361-p1/
cs361-p1/.hgignore
cs361-p1/Make.config
cs361-p1/Make.src
...
Compile base source code
Assuming you just extracted the code as shown above, you can compile the code
using the make
utility. Note that make
is not a
compiler. Rather, it is a project
management utility that can be used to automate compilation and other
tasks. This is a common tool used in the CS community and you should become
familiar with it as soon as possible. When you run make
from
the command line, it looks for a file called Makefile
. This file tells
the utility what to do. You should consult the video lectures for an overview
of how Makefiles work. In this case, running make
with no arguments
causes the following compilation steps:
$ cd cs361-p1
$ make
mkdir -p build/src/cmdline
mkdir -p build/src/main
mkdir -p build/src/y86
mkdir -p build/tests
mkdir -p build/tests/check
cp Makefile.build build/Makefile
cd build && make all
gcc -g -O0 -Wall -Werror -c ../src/main/main.c -o src/main/main.o
gcc -g -O0 -Wall -Werror -c ../src/cmdline/parse.c -o src/cmdline/parse.o
gcc -g -O0 -Wall -Werror -c ../src/y86/elf.c -o src/y86/elf.o
gcc -o ydi src/main/main.o src/cmdline/parse.o src/y86/elf.o
At this point, you can now run the compiled program:
$ ./build/ydi
Congratulations, you have compiled your source code!
False warnings from make
You may occasionally see warnings like the following. This often
arises when you are working on a virtual machine system, which is what
stu
is. In most cases (especially in this class), this is not a
problem and you can ignore the warnings.
make: Warning: File `hexdumper' has modification time 1.6e+02 s in the future
make: warning: Clock skew detected. Your build may be incomplete.