Getting started with bash
Let us assume that you have installed cygwin, have found out how to
start it ("cygwin" on desktop or in the start menu), and now are left
with a black, daunting window telling you something like
sverre@home-sverre3 /home/Sverre
$
|
Basic basics
What you see is the "prompt" that bash prints to tell you that it is
ready. Now, you are ment to write commands for the shell to
execute. There are a number of commands that are handled directly by
bash, but the point of it all is to start other programs you have
installed on you computer.
So, if you write e.g. "adsf" (and then the enter key :-) bash will
search through all the directories listed in the PATH environment
variable to see if it finds a program - "an executable" with this
name, and, if so, starts it.
environment variables: the shell maintains a list of
name=value pairs that are made available to the programs it
starts. (That is, only the ones marked as "export" are passed on).
Try issuing the command "set"; it will list all the evironment
variables in your shell. Can you see the PATH directory list ?
Note that your current directory "." may not be in the path. This
means that if you have proudly made your first program or script and
want to run it, you need to specify where it is, even if it is in the
current directory. (that is typicly "./hello"). Forgetting this can be especially
frustrating if your program is called "test" since it will then successfully run
/usr/bin/test which will do nothing :-)
You terminate the shell by typing "exit" or the end-of-file character Control-D
Some "console application" conventions
Some programs will open their own windows to do user
interaction. However, programs that are made to run from a shell will
adhere to some standards:
-
They take arguments on the command line: You can specify
options, modifying the default behavior of the program or give it data
(e.g. filenames for the files it should work on). Whatever you write
on the command line after the program name will be passed to the
program.
-
Console applications relate to three standard "data streams"; stdin,
stdout and stderr. The program can read from stdin and write to stdout
and stderr. By default stdin is mapped to keyboard input, and output on
both stdout and stderr is written to the console (shell) window. Learn
more about how to manipulate these under pipes
and redirection.
-
Console application returns a value to the shell when
terminating. Typicly this is used to signal success or failure. When
plainly running commands in the shell this value is not used, but you
can test for it, and "make" depends on this to know whether a command
was successful or not.
File name expansion
The shell processes the command line before it starts the program!
One of the things it does is expanding filenames with wild-cards. That
is, if "*.c" (without the quotes :-) is given on the command line this
will be replaced by a list of all c files in the current directory
before the program is started. The program will know about
this. '*' will match any number of characters, while '?' will match
exactly one character.
Some simple commands to try out
This is a set of commands that you can probably use right away,
without needing to study the commands in greater detail.
Still; you should cast a glance at the man-pages for them anyway to
be aware of the complete functionality and the set of options and arguments.
| man |
Displays the manual page for the given command (try "man man"). If you
do not find the manual page for some of the commands given on these
pages, I would guess that it is because it is one of the commands that
are handeled directly by bash - see if you find it at "man bash".
|
| pwd |
"Print Working Directory" - tells you in which directory you are.
|
| ls |
ls lists the files in the current directory
|
| cat |
(From "conCATenate" i believe). Reads the given file(s) and prints it
to stdout. If not files are given it reads from stdin. Note that ^D (control-D)
is "the unix end of file"
|
| cd |
"Change Directory". Give the name of the directory you want to be your
new current directory - either relative to where you are, or absolute,
relative to the file system tree "root" at "/".
|
| cp |
"Copy" a file: "cp hello1.c hello2.c" will make hello2.c a copy of hello1.c
|
| mv |
move (and/or rename) a file.
|
| rm |
remove/delete a file.
|
| mkdir |
makes a new directory
|
| rmdir |
removes a directory
|
| grep |
"grep <pattern> [list of files]" will search through the files and
print any lines that contains the pattern.
|
| ps |
Lists the processes that are running at the time.
|
Here is a bash example session:
sverre@home-sverre3 /home/Sverre
$ mkdir ctest
sverre@home-sverre3 /home/Sverre
$ cd ctest
sverre@home-sverre3 /home/Sverre/ctest
$ cat >hello.c
#include <stdio.h>
int main(){
printf("hello world\n");
}
sverre@home-sverre3 /home/Sverre/ctest
$ make hello
gcc hello.c -o hello
sverre@home-sverre3 /home/Sverre/ctest
$ ./hello
hello world
sverre@home-sverre3 /home/Sverre/ctest
$ cd ..
sverre@home-sverre3 /home/Sverre
$ rm -rf ctest
sverre@home-sverre3 /home/Sverre
$
|
Some explanations to what happens here:
-
cat >hello.c
- No file is here given to the cat command;
that is, it reads from the keyboard. Then it outputs the read text to
stdout, but this is redirected (see pipes and
redirection) to the file "hello.c". That is, whatever I wrote
ended up as the contents of "hello.c". I terminated the typing of the
C program with a ^D.
-
make hello
- "make" comes with a set of predefined rules, amongst other thing
enabling it to relate to simple C programs without requiring a
makefile. That is, it knows what to do.
Cygwin and your windows file system
Cygwin creates a unix-like file system relative to where it was
installed. The root directory "/" in this filesystem correspond (on my
system) to the windows directory "c:\cygwin".
Well and good, but how do we access the other files on the disk ?
The windows disks are "mount'ed" under /cygdrive - that is,
/cygdrive/c is the file system root of your C-disk. Go from there.
sverre@home-sverre3 /home/Sverre/tool/html
$ ls /cygdrive
c/ d/ e/
|
OK, so what about network disks ? You can, of course, use windows
to mount these under a drive letter - it will then be available like
the other disks. You can also access them directly by giving server
and share-name:
sverre@home-sverre3 /home/Sverre/tool/html
$ ls //hendseth2/homes/test
matte matte.c matte.c~ spoc/ swig/ tcl/
|
"hendseth2" is the server name in my home network, "homes" is the
share name (yielding my home directory there), and "test" is a
directory I have on that machine.
Processes
If you issue a command and start a program this will become a "process".
You can list your processes with the "ps" command:
sverre@home-sverre3 /home/Sverre/tool/html
$ ps
PID PPID PGID WINPID TTY UID STIME COMMAND
I 3556 1 3556 3556 0 1003 Aug 31 /usr/bin/bash
3088 3556 3088 3088 0 1003 20:24:33 /usr/share/emacs-21.3/bin/emacs
3900 1 3900 3900 1 1003 09:37:35 /usr/bin/bash
I 3996 1 3996 3996 2 1003 14:50:51 /usr/bin/bash
3024 3900 3024 3960 1 1003 15:37:05 /usr/bin/ps
|
You can see that when writing these pages I have 3 bash shells
running, an emacs editor, and of course the ps command.
Some things you can do to interact with processes:
-
Run a process in the background
By entering an '&' at the end of the command line the shell
will start the command as usual, but return and give you a prompt
right away. The process will be "running in the background" and will
not receive anything of what you type on the keyboard. (It can still
emit things to the console window though, through stdout and
stderr. Hmm. This is the way I experience it, though the bash manual
pages say that a background process trying to write to the console
will be suspended... I lack some understanding here...)
Be aware that if the process needs input from the keyboard it will hang.
A process not started in this way receives input from the
keyboard on stdin, and is the "foreground" process. The shell will
wait for this to terminate before giving you a prompt again.
-
Send signals to a process
The "kill" (bash builtin) command can be used to send different signals to a
process. You need to know the "process id" - PID - though; run "ps"!
Some of the signals you can send are the following: SIGTERM "asks the
application to terminate". Some programs handles this signal and may
refuse to quit - SIGKILL is a stronger variant that terminates the
program "without asking". SIGSTOP suspends the process and SIGCONT
resumes it again.
-
Suspend and resume the foreground process
If you type Control-Z when you have a foreground process running, it
will count as a suspension signal - the shell will suspend the process
and give you the prompt. The command "fg" ("ForeGround") will resume
the shells notion of the "current job" (the last command line started
that was either started in the background, or started in the
foreground and suspended) - just like if you had not typed Contol-Z in
the first place.
The reason for introducing the "job" term is that one command line
might start more than one process.
-
Continuing the "current job" in the background
The "bg" ("BackGround") command will resume the current (suspended) job, but
without connecting it to the keyboard. The job will run in the
background and the shell will return with a
prompt right away.
-
Asking a process to terminate
If you have a foreground process/job runnning you can type Control-C
to send it a SIGTERM signal.
|