The purpose of this lab is to become familiar with some Unix commands for system administration and general savviness. These are not universal to operating systems in general, but most of these skills will come in handy at one point or another during the labs later in the semester. That is why we are learning them now.
For most of this lab, you will need a terminal prompt. If you are using the KDE environment, you can click on the picture of a terminal in the bar at the bottom of the screen. (You can also choose System->Terminals->Konsole under the star menu.) You can open up several windows in this way, if for example you have several projects going at once.
Root Privileges and SUDO
The administrator account in the Unix OS is called root. Only root may modify certain system-critical files such as /etc/fstab. Because the root account is so powerful, it is tempting to use it all the time. However, this is a bad idea because one moment of inattention can cripple the system by erasing critical files or performing some other action that would be forbidden to an ordinary account. Therefore, most administrators perform most of their work using an ordinary user account, and only invoke root privileges when necessary. Unix provides a convenient way to do this, via the su (superuser) and sudo (superuser-do) commands. The su command creates a new shell environment with root privileges, which can be used to enter a sequence of commands, while sudo is used to execute a single command with root privileges. After su, exit is used to return to normal mode.
In order to be able to use the sudo
command you
need to add yourself to the list of sudoers. This is
accomplished by editing the file /etc/sudoers
as
root:
[me@localhost me]$ su Password: (enter the root password here) [root@localhost me]# emacs /etc/sudoers
Locate the section User privilege specification, and add the line shown below in bold:
... # User privilege specification root ALL=(ALL) ALL me ALL=(ALL) ALL ...
where instead of "me
" you will type your
user name. After saving the file you will be able to use
sudo
immediately. You will see a short lecture on the
screen, and will be expected to enter your (user) password.
Adding a User
As root, you can add a new user account to the system. There are two ways to do this: using the graphical interface, or via the useradd command. Read the manual page to learn how useradd works:
$ man useradd
If you do not specify a password, the account will be disabled. Once created, the password to the account can be changed by the user herself or by root using the passwd command. Thus if a user forgets the password, the system administrator can reset it. Passwords are stored in encrypted format, and there is no way for anyone to view them, even the sysadmin. A superuser can look at the encrypted passwords:
$ sudo cat /etc/shadow
The command above prints the shadow
file on the
screen, showing the encrypted password of every
user. Normal users do not have permissions to view this
file. However, thanks to the sudo
command, the
user me
can view it.
File Ownership and Permissions
You may already have seen Unix file permissions in your other courses. Each file in Unix has an owner and belongs to a particular group. The file has a permission set associated with the owner, the group, and the rest of the system, specifying how it may be used. Each set consists of three bits, specifying whether the file can be read, written, or executed. (For directories, the execution bit controls whether the directory contents can be listed.) The permission bits may be seen using the ls -l command. The permission set may be changed by the owner or by root using the chmod command.
$ man chmod
In addition, root may change the owner or group id of a file using chown and chgrp. (These commands are typically only available to the superuser.)
$ man chown $ man chgrp
![]() |
Q2. How would you create a file that nobody can read, write or execute? Can such a file be deleted, once it has been created? |
Shell Scripts
Often a sysadmin will have tasks she performs often, and perhaps even wishes to automate (see below). There are a number of ways to accomplish this, including writing a program to do it in C, Perl or Python. Another way, sometimes easier, is to write a shell script. (In DOS/Windows, the equivalent is a batch file.) This is a file containing a sequence of shell commands (i.e., things you would type into a terminal; the program that receives terminal commands and executes them is called a shell). In this way, you can bundle several commands into a package which can be executed with a single command. Take a look at this very simple shell script, and save it in your working directory.
Shell script programming can become very complex, with variables, loops, conditionals and so on, just like regular programming. We won't go into too much detail on shell scripting, but if you're interested there are many resources available on the web. A particularly good one is here. (Of course, if your script gets too complex, it may be advisable to rewrite it in a more suitable language such as Python.) The situation is further complicated by the fact that more than one shell program is available for Unix, and each one requires a slightly different syntax in its shell scripts. Each user has a default shell, which can be set using the chsh command. A shell script with its executable bit set should have a default shell specified via a comment in the first line, as shown in sample.sh. Alternately, you can execute a shell script explicitly as an argument to one of the shell programs, which need not be the same as its default script. Available shells on a system are listed in the /etc/shells file.
$ /bin/bash sample.sh $ chmod u+x sample.sh $ sample.sh $ /bin/sh sample.sh
Shell scripts are particularly useful in adapting the terminal environment to your needs. Each user's home directory can contain hidden script files that are run during login, logout, shell initialization, and during the startup of some programs. (In Unix, any file beginning with a . character is hidden, and will not show up in normal directory listings. You can see all the hidden files and directories with ls -a.) Of interest at the moment is the .bashrc file, which is executed each time a bash shell starts up. (Mandrake Linux gives users bash as their default shell. Other Unix systems use different default shells, such as csh and tcsh. These have their own hidden startup files, e.g., .cshrc, pronounced "C-shark".) Open your .bashrc file in an emacs window. You can customize it to do whatever you like. For example, try adding the following lines at the bottom, save the file, then open a new terminal window.
echo "Thought of the day:" fortune
You may also wish to add the line below to your .bashrc file. It adds the current directory (.) to your path, the list of directories searched when you attempt to run a program (i.e., enter any command). Because the path is searched in order, you want to add the current directory at the end. Otherwise, you could be caught by a "trojan horse" program, where a program in the current directory with the same name as a commonly used command (say, ls) is run instead of the standard system command. Such a program could do something malicious with your account and then run the standard version, leaving you none the wiser. Anyway, here's how to add to your path:
PATH=$PATH:. export PATH
Batch Jobs
We are accustomed to running programs and having them start right away. This was not always the way computers worked; in the days of the mainframe one would submit a job to the computer technicians with the understanding that it would be run eventually when the other jobs ahead of it were finished. A remnant of this arrangement survives in Unix's batch command, which holds a job until such time as the computer's processor is relatively free. (This differs from normal execution, where a process starts executing immediately, and therefore starts drawing CPU resources immediately.)
$ man batch
The at command is closely related, allowing a process to be run at a prescheduled time. If that process is a shell script, it can do any number of things, including scheduling yet another at job. Regularly recurring events can also be set up for common system administration tasks using the cron daemon.
One complication with batch and at jobs is that they do not by default send their output to the terminal. You can override this behavior using Unix output redirection, sending the output to the special file representing the terminal you are using. You can find out what this file is using the tty command.
$ man tty $ tty /dev/pts/1 $ batch warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh at# echo "This should appear on the terminal." > /dev/pts/1 at# echo "This should not." at# <CTRL-D>
![]() |
Q3. Set up an at job to send yourself a message one minute in the future (Hint: use echo for the message itself). |
Other Topics
Here are a few other topics to look into. The tar command (the name is short for tpe archive, a throwback to the days when tapes were much more commonly used) allows you to combine a set of files and directories in a single file for more convenient transportation and/or storage. The stored files and directories can later be reconstituted with all their structure in place. Note that tar does not compress the data in the files; this can be done by a data compression utility such as gzip. The result is a file with a .tar.gz suffix, or .tgz for short. (The latter is a concession to Windows, which deals poorly with files having more than one dotted extension.) A gzipped tape archive is the Unix equivalent of a zip file.
$ man tar $ man gzip $ man gunzip
The alias command lets you give a new name to some complicated command sequence, or alternately to change the behavior of an existing command by aliasing it to some other one. If you have any favorite aliases, it is common to include them in your .bashrc file (or equivalent) so that they will be executed each time you open a terminal window. For example, your professor uses an alias called untar that contains all the necessary command line arguments for extracting a .tar file. One important note: if you use an alias to override an existing command, but for some reason you want the original command to execute instead, put it in quotation marks. For example, student CS Unix accounts at Smith have the line alias emacs "emacs -nw" in their .cshrc file. This causes emacs to open in terminal mode instead of trying to open a new window on the desktop -- useful if students are connecting via a remote terminal like Secure Shell. But if they are actually sitting at a desktop machine, it is nicer for emacs to have its own window. Invoking "emacs" instead of emacs avoids the alias and makes emacs open its own window.
The alias command without any arguments prints a list of all aliases currently in effect.
$ alias alias l.='ls -d .* --color=tty' alias ll='ls -l --color=tty' alias ls='ls --color=tty' alias vi='vim' $ alias longls='ls -l' $ alias alias l.='ls -d .* --color=tty' alias ll='ls -l --color=tty' alias longls='ls -l' alias ls='ls --color=tty' alias vi='vim' $ unalias longls $ alias alias l.='ls -d .* --color=tty' alias ll='ls -l --color=tty' alias ls='ls --color=tty' alias vi='vim'
The ln command establishes a symbolic link to a file or directory. (This is analogous to shortcuts in Windows or MacOS.) It is useful if there are system directories that you often access.
$ man ln
![]() |
Q4. Combine shell scripts, the alias command, and the at command to create a safer verion of rm. The standard rm deletes files without any possibility of recovery. This is not very user-friendly, which is why Windows and MacOS provide a trash can from which deleted files may be retrieved. Your job is to make rm operate in a similar manner. Instead of deleting a file, make rm an alias for a shell script that moves the file to a special directory (/home/username/.trash) and compresses it for space savings. (You will need to write a script that takes an argument, as shown in this example.) Then write a second script, designed to run every night at 4:00 am, that erases the contents of the trash directory and reschedules itself to run on the following evening.) Be sure to test your script under a number of different conditions to make sure that it works. |
![]() |
Q5. Extra Credit. Design your new rm script so that it avoids naming conflicts. If two files with the same name are deleted, the first one will be overwritten and lost unless the situation is detected and addressed. Make your rm script check for the existence of a file with the same name in the trash directory. If it finds one, it will have to rename it somehow. (To complete this task, you will need to look at some of the examples of conditionals in the shell script tutorials.) |