The purpose of this lab is to learn how to create and manage directories, view and manipulate file permissions, compile a program, and manage your processes (executables).
Read the entire contents of this page before beginning the lab work at the bottom of the page.
LAB 2 VIDEOS
The following videos walk you through the contents of Lab 2. You should read this page, then follow along on the videos to complete the work at the bottom of the page:
BASIC DIRECTORY MANIPULATION
You can create directories and subdirectories to organize your files, just as you can create folders in a graphical user interface (GUI). It is recommended that you create a directory for each class and store all your files for that class in that directory to keep your files organized.
When you first login, you are automatically put into your "home" directory, which is your user-specific file space on Odin. Odin does not remember what directory you were in when you logged off, so if you want to store all of your class files in a specific directory, you have to remember to go to that directory every time you logon.
The following commands are used to create and manipulate directories, and also to move data between directories. A demonstration of these commands will be given on the projector:
pwd |
Prints the name of the directory you are currently in. |
mkdir <dir_name> |
Create a directory with the given name. |
rmdir <dir_name> |
Remove the directory with the given name. The directory must be empty for this command to work. |
ls [-al] <dir_name> |
List the files contained in the given directory name, optionally with the dot file and detailed listing options. |
ls -ld <dir_name> |
Display the long listing for the directory itself (instead of its contents). |
cd <dir_name> |
Change your current directory to the given directory name. All new files created with vi will be saved in this directory. |
cd |
Change your current directory to your home directory. |
cp <filename> <directory> |
Copy the given filename into the given directory. |
mv <dir_name> <new_name> |
Rename a directory from the current directory name to a new directory name. |
mv <filename> <dir_name> |
Move (not copy) the given filename into the given directory name. |
UNDERSTANDING FILE PERMISSIONS
Since Unix is a multiuser operating systems, all files and directories have permission flags to control access. Permission flags are set for three entities: the file's owner, a group of users, and the rest of the world. Permission flags control whether the entity can read (r), write (w), or execute (x) the resource.
Your Odin account is in group 'student'. If you give the command ls -al in one of your directories you will view the permissions set for files and subdirectories in that directory. It will resemble the following:
drwxr-xr-x 2 demostudent student 4096 2010-09-08 23:14 doc/ -rw-r--r-- 1 demostudent student 5609 2009-09-29 22:26 notesThe first part is the permission string. The first letter in the permission string is the file type (d for directory, - for a normal file). The next three letters are the owner's permissions (rwx and rw- in the above example). The next three letters are the group's permissions (r-x and r-- above). The last three letters are the world's permissions (r-x and r-- above).
The default permissions are "drwxr-xr-x" for directories and "-rw-r--r--" for normal files. This means the owner has full permissions (read/write for files, read/write/execute for directories). NOTE: You must have execute permissions on directories in order to list their contents. The group and world have no write permissions (indicated by a - where the write permission would be), but do have read permissions for normal files and read/execute permissions for directories. This means everyone can read the file and look at the directory, but only the owner can update its contents.
You can think of each permission set (rwx) as a 3-digit binary number where a 1 means to turn the permission on and a 0 means to turn the permission off. Thus a 5, which is 101 in binary, will turn on read and execute permission and turn off write permission. A 7, which is 111 in binary, will flip all permissions on. A 2 (010 in binary) will turn on write permission only and a 1 (001 in binary) will turn on execute permission only.
The command to change permissions is chmod (change mode). For instance, to change permission on a file named myfile.txt to give you (owner) rwx (read,write,execute), group r-x (read and execute), and world r-- (read only) do this:
chmod 754 myfile.txtYou can change the permissions on your directories to read only for you (make it "private") by giving the name of the directory as the second argument:
chmod 700 docIt is STRONGLY RECOMMENDED that you create a directory for each course and make that directory private. Then be sure to change into that directory using the cd command before creating any source code files for your CMPS 2010 assignments. This will ensure that your work remains private, so that other students cannot copy your work. The commands to do so are as follows:
mkdir cs2010 chmod 700 cs2010Make sure to change directories into your course directory every time you log in (
cd cs2010
). Odin does not remember what directory you were
in last so you must use the cd command on every login.
Any file you leave in your home directory will be readable by others unless you do the chmod command for that file or move the file into a private directory.
COMPILING A PROGRAM
After you have written the source code for the program, you need to compile the code into an executable. You compile the source code using the g++ command. Let's assume you created a source code file called 'lab1.cpp'. You would turn it into an executable called 'lab1' with the following command:
g++ -o lab1 lab1.cppThis will invoke the C++ compiler to create the executable. If there are any errors in your program, the executable will not be made. Instead, you will get a list of errors in your source code. If the executable is made correctly, nothing will display on the screen and you will just return to the command-line prompt.
Once the executable is made, you would then run the executable with the following command:
./lab1You must include ./ before the executable name on Odin to tell Odin you are aware that you are running an executable in your current directory. This is a security precaution to prevent an attacker from dropping an executable named after a command (say an executable named "ls") in your current directory and having you run the attacker's executable instead of the system command. Some instructors will show you how to disable this precaution, but be aware it can leave you vulnerable to this sort of "trojan horse" attack.
COPYING AND PASTING IN VI
Sometimes you will be given a source code example on an assignment that you need to copy into your source code file and modify. When using vi, you must first tell vi that you are pasting code, or it will automatically indent the code in an odd fashion.
To enable copy/paste from the mouse, give the following last-line vi commands. You cannot be in insert mode when giving these commands, so be sure to hit ESC first:
:set paste
- Give this command before entering insert mode to enable correct pasting. This disables automatic indenting so the text will be pasted correctly.
:set nopaste
- Give this command after pasting in insert mode (hit ESC to go back to command mode). This will enable automatic indenting when you go back into insert mode.
PROCESSES AND HOW TO MANAGE THEM
A process is an executing program under Unix/Linux. Each process has an owner
(generally the owner of the executable file) and a unique process ID known as
the PID. As the owner of a process, you can tell Odin to stop the process,
which is knowing as "killing" the process. You can only kill processes that
you own, so don't be concerned that a mistake might crash the server (see
man kill
). As you begin writing programs, you often need to use
the kill command to kill a program stuck in an infinite loop or a frozen shell
process.
The first way one can control a process is to send a control character to the
currently running process (the foreground process). For example, if your
program is stuck in an infinite loop, you can try to send the control
character for kill. Control characters are initiated by holding the CTRL key
and hitting another character, such as CTRL-C
(written as ^C
). The hat
(^)is used to represent the CTRL key. The common control characters are:
^C
sends a kill signal to the foreground process ^Z
suspends the foreground process ^D
sends an EOF signal to the foreground process
Some processes can ignore the control signals, so the control characters will
not always work. If the control character does not work, you will need to use
the kill [-9] <PID>
command. In order to use this command, you
first need to discover the PID for your out of control process. To do this,
you will use the ps
command.
The ps command has many options that affect which processes it shows you. By default, it will just show you the processes for your current login session. But if one login is stuck in an infinite loop, you will need to start a second login session to kill the stuck process. To view all of your processes, use one of the following commands:
ps x // Shows all processes owned by you ps ux // Shows detailed information for your processes ps -ef | grep <username> // Filters all processes, looking for your usernameThe last command makes use of the pipe character (|) to redirect the output of the ps command into the grep command, which filters the data and just displays the entries that match the given username. You might also want to redirect the output of ps into a file (particularly if you have a lot of files) so you can use a text editor to view them. Let's say we want to redirect
ps ux
into a file called process_list.txt. The command to do that
is:
ps ux > process_list.txtOnce you have the list of processes, you need to look for the line that contains your runaway process. The number towards the start of the line (under the PID column) is the PID for the process. We can then give that to the kill command. For example, if the PID is 12345, the kill command would be one of the following:
kill 12345 // Politely request that the process exit. Can be ignored. kill -9 12345 // Demand that the process exit immediately. Not ignored.Note that your login shell is actually a process, so you can use the kill command to kill your other login sessions. This can be a useful failsafe if you forget to logout and realize it when you're at home. You can login, find the PID of your idle session on campus and kill it to force a logoff.
One final note on processes. Foreground processes can be sent to the background when you want to keep using the shell prompt for other tasks. This is useful when the program does not need user interaction. To start a program in the background, append an ampersand (&) to the command:
cat & // Start cat in the backgroundMake sure that the program can complete in the background. Otherwise, it will sit there and do nothing as it waits for the user to type something. To see all your current background processes, type the command
jobsTo bring a background process back to the foreground (so you can type something that it is expecting), use the command
fg <job_number>Job number is listed in the output of the jobs command and is NOT the PID.
WHAT TO COMPLETE FOR THIS LAB
Now you are ready to perform the tasks below (It is assumed you have already logged into your account.) When you have successfully finished all items, and before logging out, ask a student assistant to check your terminal history to show that you have completed all of the following items. You will only receive credit by showing your work to a student assistant.
- Make a subdirectory in your home directory for this course.
mkdir cs150
- Set the permissions on your cs150 directory so that you have full access,
while group and world have no access. You must determine the correct
permission string to get credit for this question.
chmod <permission> cs150
- Display the directory permissions for your cs150 directory.
ls -ld cs150
- Copy junk.txt created in the first lab from your home directory into the
new subdirectory. Make sure to COPY the file so it exists in both your home
directory and cs150 subdirectory.
cp junk.txt cs150
- Display the contents of the cs150 directory with the detailed (long)
listing option.
ls -l cs150
- Change directories to the new cs150 subdirectory.
cd cs150
- Delete the copied junk.txt file from your cs150 directory.
rm junk.txt
- Change back to your home directory.
cd
- Remove the cs150 subdirectory. This will only work when you've completed
the previous two steps correctly.
rmdir cs150
- Create a file with vi called hello.cpp. The file should contain the
following (use copy/paste commands from above):
#include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; }
- Set the permissions on hello.cpp to give you full permissions, give group
read only permissions and give world no permissions.
chmod <permission> hello.cpp
- Display the permissions on hello.cpp
ls -l hello.cpp
- Compile hello.cpp into an executable called hello.
g++ -o hello hello.cpp
- Run the hello executable.
./hello
- Run the cat program in the background.
cat &
- List all of your processes and find the PID of the cat process.
ps ux ps x ps -ef | grep <username>
- Try to kill the cat process and see if it worked by using the ps command.
Repeat until all the cat processes are killed.
kill [-9] <PID>
- Redirect the output of the ps -ef command into a file called file1.txt
ps -ef > file1.txt
Once that is done, BE SURE TO LOGOUT (exit
command).