Unix Advanced

From Redbrick Wiki

Advanced Unix Commands

This page is for those who are used to redbrick by now and want to learn how to do more advanced stuff such as running multiple programs at the same time from one terminal window etc. Processes

A process is a program that runs when you execute a command in UNIX. You can have more than one process running at a time, which obviously means you can have more than one program running at a time. "How can this be, Conor!?" you shout at me. I cover my ears and respond that you can run some programs in the background or you can put some programs on hold while you do something else equally crazy. And here's how you do all this magic UNIX stuff!

Suspending a Process

You can put a process on hold so that you can run another program and then come back to it later. Say for example you are reading the newsgroups and someone heys you and you want to reply but you are in the middle of a very deep posting on redbrick.debate. Well all you have to do is press CTRL and Z together on the keyboard and it will "suspend" slrn and bring you back to the shell, now you can hey as normal until you're ready to go back to the newsgroups, in which case you type fg and press enter. This will load up slrn exactly where you left off. Ta da!

Jobs

Jobs are similar to processes except that jobs are controlled by the shell they're running under, whereas a process could be running on its own without a controlling terminal or shell..(sometimes processes without controlling terminals and in their own process groups are known as "daemons").

Processes forked off (I say "forked off" because the shell program (e.g. bash) normally uses a system function called fork to create a child process which then calls a function named exec to execute whatever program is being run..) by a shell automatically belong to the same process group as the shell, so if the shell exits, so do any other processes in its group since the shell is normally the process to create or own that particular process group id. (This last paragraph has been all an aside so don't worry if you don't have a clue what I'm on about 'cause you're not the only one :o) )

Restoring a process

If you suspend a process, or job, as mentioned above, you can start another process while you have a process suspended. You can also have more than one process suspended at a time. This means that when you type fg it will bring up the last program you suspended. However you may want to bring up a job you suspended a while back, which isn't the last job you suspended. (Confusing huh?:o))

To see a list of the jobs or processes you have suspended at any time, type jobs at the prompt. On the left of the list of programs on each line you will see a number in brackets. This is the number of that job. To unsuspend that particular job you type fg followed by a % sign and the number of the job. Agus this will do the trick :o)

In the following example I check what jobs I have running and then bring one of them into the foreground (that's what fg stands for..):

prompt$ jobs
[1]  - 63132 suspended (signal)  mutt
[2]  + 63142 suspended  slrn
prompt$ fg slrn
[2]  - continued  slrn
prompt$					 <cokane@prodigy ZSH emacs 16:58>
In the above example, if I were to restore slrn by its job number I would type:
fg %2

As an aside, the (signal) bit beside mutt means it was suspended by a signal. This is exactly what CTRL Z does. It sends a signal to a program telling it to stop.

Background jobs

Some programs might take a while to run before printing anything, or they may not print anything at all...

With programs like these it seems a waste to let the shell just sit there waiting for them to finish when you could be heying friends or doing something else. There's a solution to this: run them in the background. You already saw the shell command fg which puts a suspended program back running in the foreground. Well there's a corresponding command to run a program in the background .. that's right.. bg :o)

bg works exactly the same as fg in that it takes a program name or job number as it's argument.

That's pretty much all there is to running jobs in the background. You can also explicitly tell a program to run in the background by appending an ampersand to the command, like so:

prompt$ top &
[1] 3984
prompt$ 
[1] + suspended (tty output)  top
prompt$

Killing Processes

Don't worry, it's not as evil as it sounds ;o) Sometimes you might not be able to quit a program, or log out properly. A program you're running might have gone into a loop and you mightn't be able to quit out of it, or you might be telnetting or SSHing into redbrick from work or home and you might get logged out because your mam plugged out the phone line or your boss reefed you dossing or something equally unfortunate and when you log back in you see that you're still logged in and you want to log out of that other session.

Well what you can do is you can kill that process; basically this is a fancy way of saying you can close the program down. To do this you just type ps at the prompt. This is slightly different to the jobs command as it shows the processes running under your username, wheras jobs just shows what jobs are suspended in that particular shell session.

When you type ps -fU yourUserName you will see the rightmost column tells you the name of the process. You will see that for each time you are logged in you are running the shell program, bash, zsh or whatever. The leftmost column you will see is called PID. This stands for Process ID, that is the number associated with that process.

To kill a particular process just type kill -9 followed by the process number. The -9 means that the process will be closed immediately, it doesn't give it a chance to shut down by itself, it just closes it down as soon as the command is run. In the next example I show the output of ps then I kill one of my processes.. slrn :

prompt$ ps -u
USER     PID %CPU %MEM   VSZ  RSS  TT  STAT STARTED      TIME COMMAND
cokane 66980  0.0  0.2  1260 1036  pi  Ss    5:22PM   0:00.24 -zsh (zsh)
cokane 68730  0.0  0.3  1620 1324  pi  T     5:36PM   0:00.02 slrn
cokane 68741  0.0  0.0   388  220  pi  R+    5:36PM   0:00.00 ps -u
prompt$ ps
  PID  TT  STAT      TIME COMMAND
66980  pi  Ss     0:00.24 -zsh (zsh)
68730  pi  T      0:00.02 slrn
68749  pi  R+     0:00.00 ps
prompt$ kill -SIGKILL 68730
[1]  + killed     slrn
prompt$

As you see above I run ps twice. The first time I run it with the 'u' switch. As you see this gives more detail about processes such as the amount of CPU time and memory that they are taking up.

Command shows the name of the process..

Time shows how long the process has been running so far. Notice here that zsh seems to only have been running for 24 seconds..This is because the shell itself rarely does much work other than forking off processes.

Stat shows the status of that particular process. Now most of these symbols are a mystery to me but I know that 'I' means it's on idle, and 'R' means it's running.. or something :o)

TT is the name of the terminal the process is associated with, if any. In this case I am logged on from /dev/ttypi and all my processes are associated with this terminal.

PID is the process id of that particular process. In the spirit of throwing in asides (which are often inaccurate) in this article I'll point out that the Linux version of kill doesn't need the pid of the process you want to kill. You can simply pass the name of a process to kill in Linux and it will kill it (assuming you are root or you own the process). There is a Linux-alike version of kill on FreeBSD but normal kill on FreeBSD doesn't support this as far as I know...

You see in the above example that when a process gets killed (or finishes itself), the shell will print that the process has finished or has been killed. In the above example you can see that it shows the job number in square brackets, then the reason the process returned (that it was killed) and the name of the process.

Signals

Now I will (attempt to) explain signals in UNIX...

As you saw above, when I ran kill I passed it the argument of -SIGKILL or -KILL (whether or not you leave in the SIG part is up to you, some versions of kill might mind not having it though..). The program kill, despite it's name, is't solely cocerned with killing processes. It's main purpose is to send "signals" to processes. In the above case we send SIGKILL which is the kill signal used to kill a process.

Below I will list some of the most common signals and what they're used for. I reserve the right to be very wrong about some of them :o)

  • SIGKILL

As explained already... to kill a process

  • SIGTERM

Similar to SIGKILL but it won't kill the process straight away.

  • SIGSTOP

This is the signal which suspends a process..

  • SIGSTP

Similar to SIGSTOP, this is the signal that pressing CTRL + Z sends.

  • SIGCONT

The signal sent to continue a suspended process.

  • SIGTTOU

This occurs when a process running in the background attempts to write to the terminal. The process gets suspended.

  • SIGTTIN

As above except occurs when process tries to read input from terminal.

  • SIGHUP

The "hang up" signal, nowadays sending this to a process will cause the process (if it's a daemon) to re-read its configuration files without you having to restart the process itself.


Sometimes you will see people recommend that you type: kill -9 followed by the process id, to kill a process. This is identical to typing kill -KILL. Indeed if you type the following at the shell :

cat /usr/include/sys/signal.h |grep SIGKILL

you will see that SIGKILL is just an alias for the number 9 and the same applies for the other signals (i.e. that they are all aliased to different numbers..)

There ends my sucky sig explanation ;o)

Hopefully you've found this tutorial a bit helpful and have maybe learnt something as well from it as well.

Links

Unix Intro - basic Unix commands, just in case you forgot them or something...

Helpdesk - more tutorials!