Beruflich Dokumente
Kultur Dokumente
#!/bin/bash
echo -n "password: "
read pass
echo "Your pass is $pass"
save & exit --- then do this command: chmod u+x myscript.sh
Then we can execute it:
alien:~$ ./myscript.sh
password: <type what you want>
Your pass is <what you typed>
alien:~$
The "#!/bin/bash" at the start of the file is to let the script know what
shell type it should use.
The "chmod u+x myscript.sh" is to make it executable.
(change-mode user+execute-right-on myscript.sh) ..... read the manual pages
on chmod for more info on it =)
-------------------------------------------------------------------------------
Take alot of time to play around in your system, open files, figure out
what they do (but don't edit or remove them).
Take time also to learn some good text editor, that's important.
Learn, emacs or vi, those are by most people considerd the absolutly best,
but jed, joe, elvis, pico or any simple editor like that will do
just fine for now.
emacs and vi are explained later in this tutorial.
-------------------------------------------------------------------------------
Another thing before moving on is that you can export a variable from a
script.
Say that you have the variable "$var" in a script and want to export
it to the system for use with some other script or something, you can
do: export var
Like this little script:
-------------------------------------------------------------------------------
#!/bin/bash
VAR="10"
export VAR
-------------------------------------------------------------------------------
Note: VAR="10" can not be written as VAR = "10", since it's
'whitespace-sensetive'.
-------------------------------------------------------------------------------
But more to how to make scripts in a second, I just thought that this would
be a good time to enlighten you about this.
So here we go ....
===============================================================================
3 - Beginning techniques.
===============================================================================
First off I'm going to show how to count in bash or how to use your command
line as a calculator, which is really easy and useful.
alien:~$ echo $[ 4 * 2 ]
8
alien:~$
or another example:
alien:~$ echo $[ 10 + 5 ]
15
alien:~$
Easy ? .... I think it is =)
The internal calculator can also be used like this:
alien:~$ echo $(( 10 + 5 ))
15
alien:~$
The second way of using the internal shell calculator is here just
so you dont get confused if you see it used that way sometime.
-------------------------------------------------------------------------------
Now I'd like to show the *string comparing* with "if" statements,
which can be a little hard at first contact, but as soon as you get
familiar with it, it wont be any problems.
So here's an example.
-------------------------------------------------------------------------------
#!/bin/bash
echo -n "enter a name: "
read var1
echo -n "enter another name: "
read var2
if [ "$var1" = "$var2" ]; then
echo "The names are the same"
else
echo "The names were not the same"
fi
exit 0
-------------------------------------------------------------------------------
Note: "fi" is the ending of if, just like a "}" is the ending of a "{",
exit 0 terminates the script correctly and returns you to the prompt.
Another note is that instead of '=' you can use '-eq' to test if
2 expressions are equal, or '-eg' to check if 2 integers are equal, etc.
It should also be said that a variable say '$var' can be written
as this: ${var}, just so you know if you see it done that way
in some scripts, but here we will use the $var way.
-------------------------------------------------------------------------------
This example if executed looks like this:
(Matching names)
alien:~$ ./script1.sh
enter a name: smurf
enter another name: smurf
The names are the same
alien:~$
(Non-matching names)
alien:~$ ./script1.sh
enter a name: smurf
enter another name: guru
The names were not the same
alien:~$
You can compare any 2 strings with this, as this *mid script example*:
...
if [ "$user" = "gnu" ]; then
echo "Hello user gnu !"
else
echo "I don't know you."
fi
...
This compares a variable with a static string which you can set to anything.
You can also do this the other way around.
...
if [ "$user" != "gnu" ]; then
echo "I don't know you."
else
echo "Hello user gnu !"
fi
...
The '!=' means NOT-IS, in clear text if the 2 strings are not a match.
As the above example in straight English:
...
if the variable don't match the word gnu, then
say "I don't know you."
in other cases
say "Hello user gnu !"
...
If you think that a variable may not contain anything and you wanna avoid
it showing you errors you can add an x as the first character to both
the statements to test with if, like this to compare $one with -x:
...
if [ "x$one" = "x-x" ]; then
echo "$one is -x"
else
echo "$one is not -x"
fi
...
In plain english:
...
if (contents of $one) equals -x (supress error messages if any), then
say (contents of $one) is -x
in other cases
say (contents of $one) is not -x
...
This previous way is actually quite old, and only a precaution, say this:
...
echo -n "enter a number: "
read foo
if [ $foo = 2 ]; then
echo ok foo
fi
...
Now, if you with this example dont enter any number there will be nothing
there for if to compare with, not even a blank "", since we're not
using quotes, but as this:
...
echo -n "enter a number: "
read foo
if [ x$foo = x2 ]; then
echo ok foo
fi
...
There will always be something, because if $foo is nothing there is
still x.
Just read acouple of times and you'll get it.
You can also test if a variable contains anyting at all like this:
...
echo -n "enter a number: "
read foo
[ -n $foo ] &&
echo ok foo
...
This uses the same options as the test command, so "-z" will return true
if the variable is empty, "-z" will return true if the variable is not
empty etc, it's ok if you dont understand this right now ....
I've added this for the second time readers.
You can also test if a command turns out as true, like this:
...
if echo "foo" >/dev/null; then
echo "foo"
else
echo "bar"
fi
...
Here if will check if foo echos to /dev/null, and if so, then it will
print out "foo" and if foo didnt echo to /dev/null, it'll print out
the word "bar"
Anoter and perhaps *cleaner* way of doing the same is this:
...
if (echo "foo" >/dev/null); then
echo "foo"
else
echo "bar"
fi
...
It's the exact same thing but with parenthases around the command,
it looks much cleaner ... and so the code is easyer to follow.
You can also make if think 'if this is a match or that is a match', like
if the variable is one of two options do one thing else do another.
Like this:
...
if [ "$user" = "gnu" -o "$user" = "ung" ]; then
echo "Hello $user !"
else
echo "I never heard of $user..."
fi
...
The '-o' means OR in an if statement, so here is the example in plain english:
...
if the variable matches the word gnu or matches the word ung, then
say Hello word ! (the word is the variable, now gnu or ung)
in other cases
say "I never heard of word... (the word is whatever the variable is set to)
...
-------------------------------------------------------------------------------
Note: The quotes are needed in an if statement in case the strings or
variables it's suppse to compare is empty, since
if [ foo = ]; then
would produse a syntax error, but
if [ "foo" = "" ]; then
would not.
-------------------------------------------------------------------------------
The '-o' can also be made with '] || [', so that:
if [ "$user" = "gnu" -o "$user" = "ung" ]; then
can also be expressed as this:
if [ "$user" = "gnu" ] || [ "$user" = "ung" ]; then
You dont really need to remember that, but for the knowlidge I desided
to make a note out of that anyway, mostly for the more experianced readers
of this tutuorial, and for the readers that have read it several times.
-------------------------------------------------------------------------------
You can also set static text in a variable, which is really easy:
-------------------------------------------------------------------------------
#!/bin/bash
anyvar="hello world"
echo "$anyvar"
exit 0
-------------------------------------------------------------------------------
Which executed would look like this:
alien:~$ ./myscript
hello world
alien:~$
Easy enough ? =)
-------------------------------------------------------------------------------
Now let's move on to "for" and common for-loops.
I am actually only going to show one sort of for-loop example, of the reason tha
t
at this stage no more is needed, and would only confuse.
as a note, for loops-can be uses (as soon shown) to import strings
from a file to be used as variables in the script.
Now, here's the example:
-------------------------------------------------------------------------------
#!/bin/bash
for VAR in `cat list.txt`; do
echo "$VAR was found in list.txt"
done
exit 0
-------------------------------------------------------------------------------
Note: "done" terminates the loop when finished.
"in" and "do" are like bash *grammar*, I'll explain that later.
The `cat list.txt` part, the `s around the command will make sure
the script/line executes that part as a command, another way of
doing this is to: $(cat list.txt)
which has the same effect.
That's just a note so you wont get confused if you see it used
that way some time.
-------------------------------------------------------------------------------
The previous script example is dependent on that there is a file called
"list.txt", so let's make such, and fill it with something like this:
list.txt
123
234
345
456
567
678
789
890
-------------------------------------------------------------------------------
Then the executed script would look like this:
alien:~$ ./script2.sh
123 was found in list.txt
234 was found in list.txt
345 was found in list.txt
456 was found in list.txt
567 was found in list.txt
678 was found in list.txt
789 was found in list.txt
890 was found in list.txt
alien:~$
-------------------------------------------------------------------------------
Note: A space in a file read by a for-loop is taken the same way as a new line.
-------------------------------------------------------------------------------
Here is another example, with a for-loop with an if statement:
-------------------------------------------------------------------------------
#!/bin/bash
for VAR3 in `cat list.txt`; do
if [ "$VAR3" = "789" ]; then
echo
echo "Match was found ($VAR)"
echo
fi
done
exit 0
-------------------------------------------------------------------------------
And executed that looks like this:
alien:~$ ./script3.sh
Match was found (789)
alien:~$
If you have read this in a calm fashion it should be quite clear to you
so far, but before I move on to real practice examples I will explain
the while-loop, and some, more which can be used as to count and more,
for various purposes, as you will see.
You don't have to *understand* all of how this works, but you should
at least learn it.
So here we go on an example with "while":
-------------------------------------------------------------------------------
#!/bin/bash
count="0"
max="10"
while [ $count != $max ]; do count=`expr $count + 1`
echo "We are now at number: $count"
done
exit 0
-------------------------------------------------------------------------------
Note: expr is a calculator command, you can read more about it later in
this tutorial.
-------------------------------------------------------------------------------
This in plain English reads the following:
make variable "count" hold the number 0
make variable "max" hold the number 10
while 0 is not 10, do add 1 to 0 (each loop until it is 10)
say "We are now at number: $count" (each time 1 is added as long as we are
in the loop)
end the loop
return to the prompt command line.
-------------------------------------------------------------------------------
Which executed looks like, (you guessed it), this:
alien:~$ ./count.sh
We are now at number: 1
We are now at number: 2
We are now at number: 3
We are now at number: 4
We are now at number: 5
We are now at number: 6
We are now at number: 7
We are now at number: 8
We are now at number: 9
We are now at number: 10
alien:~$
-------------------------------------------------------------------------------
Here is another example of a while loop.
#!/bin/bash
agreement=
while [ x$agreement = x ]; do
echo
echo -n "Do you agree with this ? [yes or no]: "
read yesnoanswer
case $yesnoanswer in
y* | Y*)
agreement=1
;;
n* | n*)
echo "If you don't agree, you can't install this sofware";
echo
exit 1
;;
esac
done
echo "agreed"
echo
-------------------------------------------------------------------------------
This in plain English reads the following:
Make an unknown variable named agreement
while the unknown variable is unknown and doesnt match the case,
say "Do you agree with this ? [yes or no]: "
read the the answer into the "yesnoanswer" variable.
make a case and check the "yesnoanswer" variable for any words beginning
with y or Y, and if so, skip the rest and go on with the script
and say "agreed".
if it doesnt begin with y or Y, check if it starts with n or N.
If it does start with a n or N, then say:
"If you don't agree, you can't install this sofware"
and quit the script.
-------------------------------------------------------------------------------
Which executed looks like this:
alien:~$ ./agree.sh
Do you agree with this ? [yes or no]: something
Do you agree with this ? [yes or no]: yes
agreed
-------------------------------------------------------------------------------
Which executed looks like this:
Without any arguments:
alien:~$ ./funk.sh
Usage: ./funk.sh <number>
alien:~$
And with arguments:
alien:~$ ./funk.sh 23
welcome
Now we will calculate 12 + 5 * 23
the answer is 391
alien:~$
------------------------------------------------------------------------------
And for the sake of knowlidge it should also be said that a function can be
declared in the following ways aswell:
------------------------------------------------------------------------------
#!/bin/bash
function foo() {
echo "hello world"
}
foo
------------------------------------------------------------------------------
#!/bin/bash
foo () {
echo "hello world"
}
foo
------------------------------------------------------------------------------
Note that the paranteses after the funtion name are the new thing here.
It's used exactly the same way as without the paranteses, I just
added that here so that you wont get confused if you see it made that
way sometime.
------------------------------------------------------------------------------
So if you make a function, to call for it (to make use of it), just use the
the functions name just as if it had been a command.
If there is anything that's uncertain at this point, go back and read it again,
until you understand it, or at least get the basic idea. =)
===============================================================================
3 - Other techniques.
===============================================================================
Now let's move on to a little bit more advanced shell scripting.
Actually it's not that advanced, just more hard to keep in order, but let us
leave that to the head of the beholder..... errr
Anyway, let's not make this harder then it is, so here we go, with a script
example:
-------------------------------------------------------------------------------
#!/bin/bash
> file1.c
cat >> file1.c << EOF
#include <stdio.h>
int main ( void )
{
printf("Hello world\n");
return 0;
}
EOF
cc file1.c -o file1 || gcc -o file1 file1.c
./file1
rm -f file1.c file1
exit 0
-------------------------------------------------------------------------------
And here as follows, is an semi-english translation of the script:
echo nothing to file1.c to create it.
cat to file1.c what comes here after in between the "EOF"'s
// --- a short hello world program in C code --- //
try if there is a 'cc', if not then use 'gcc'
Execute the newly compiled file
remove file1.c and file1
exit the script.
-------------------------------------------------------------------------------
This can be very useful, since bash do have it's limitations, so if you
ever need something more powerful or just something else, you can always
do like the script told.
Another little trick with the same thing in a script is:
more << EOF
Here you can type whatever,
like an agreement text or something.
EOF
Play around with it.
-------------------------------------------------------------------------------
Here let's have a look at the "case" command, case is like "if" ended
with it self backwards.
So that what starts with "case" ends with "esac", here's an example of "case":
-------------------------------------------------------------------------------
#!/bin/bash
case "$1" in
foo)
echo "foo was written"
;;
bar)
echo "bar was written"
;;
something-else)
echo "something-else was written"
;;
esac
-------------------------------------------------------------------------------
This is the same as saying:
....
if [ "$1" = "foo" ];then
echo "foo written"
fi
if [ "$1" = "bar" ];then
echo "bar was written"
fi
etc.
....
so case is far shorter if you have alot of arguments.
Here's a better example:
-------------------------------------------------------------------------------
#!/bin/bash
case "$1" in
--help)
echo "Usage: $0 [--help] [--port <port>] <host> [--time]"
;;
--port)
telnet $3 $2
;;
--time)
date
;;
esac
-------------------------------------------------------------------------------
This is not very hard to learn,
case the first argument vector ($1) in
firt-possible-match)
if it matches do ........
close the ) with ;;
etc. down to "esac"
Really not much more to say about the case command at this point.
-------------------------------------------------------------------------------
Now let's have a REALLY quick look at the command `sed`, which is used
to format text. say now that you have a file called "tmp" that
contains the following:
http://www.metacrawler.com
http://www.yahoo.com
http://www.webcrawler.com
and you want to change all the "www"'s to "ftp", then you do like this:
sed 's/www/ftp/g' tmp
and if you want to store the changes to a file you can do:
sed 's/www/ftp/g' tmp > tmp2
This is not sed's only use, but for sure it's what it's most used for.
Here's just one other really simple thing sed could be used as:
sed -n 3 p /etc/passwd
This will print out the 3'd line of the /etc/passwd file.
-------------------------------------------------------------------------------
Now let's take up a really interesting command `dialog`, that is a command
with which you can create ncurses dialog boxes.
Ncurses dialog boxes are what one would call 'console graphics' or
'ascii color graphics', if you ever seen a blue background and a gray box
asking questions, with an <OK> and <Cancel> button, while running
something in a console you have seen an ncurses dialog box.
Now here is a small script example of a dialog box:
-------------------------------------------------------------------------------
#!/bin/bash
dialog --backtitle "My first dialog" \
--title "Main menu" \
--menu "Make your choice" 13 60 6 \
1 "First option" \
2 "Second option" \
3 "Exit" 2> .tempfile
output=`cat .tempfile`
rm -f .tempfile
if [ "$output" = "1" ]; then
dialog --msgbox "First option was entered" 5 40
fi
if [ "$output" = "2" ]; then
dialog --msgbox "Second option was entered" 5 40
fi
exit 0
-------------------------------------------------------------------------------
Here is another very small example with dialog boxes:
-------------------------------------------------------------------------------
#!/bin/bash
dialog --yesno "Do you agree, jada jada" 10 50 && \
dialog --yesno "ok you agreed" 10 50 || \
dialog --yesno "ok fine, leav then ..." 10 50
-------------------------------------------------------------------------------
If the first one (Do you agree, jada jada) returns 'true' (yes)
then it walks on to the next (ok you agreed),
and if any of those first two returns 'false' (no) it will display
the last (ok fine, leav then ...).
-------------------------------------------------------------------------------
Notes: The back slashes "\" are used to say "no new line" as in what comes
on the next line will be treated as if it were on the same line as
the last line, the "\" really means that the next character's
(in this case the new lines) special meaning is overlocked.
Just in case you didnt understand, the numbers after, like 10 50:
dialog --yesno "ok fine, leav then ..." 10 50
is the geometry of the window.
First number is height and the second width.
Another note being that the command `Xdialog` works the same as
dialog, but I wont take that up here because it doesn't come as default
with any other Linux distribution then Mandrake, as far as I know.
A final note is that the `dialog` command is getting to be out dated
but is still the most used, the newer version of it is named `whiptail`
and works the same as `dialog`, but looks slightly different.
-------------------------------------------------------------------------------
Now we have covered most of it, so let's take up some small tricks, that bash
allows you to do, here follows what it does, and then the code example:
Here we wanna check if you have a directory called "/usr/local/bin":
if [ -d /usr/local/bin ]; then
cp file /usr/local/bin/
else
echo "NO !!"
fi
Another way of doing the same thing is this:
test -d /usr/local/bin && cp file /usr/local/bin/ || echo "NO !!"
Or:
ls /usr/local/bin/ && cp file /usr/local/bin/ || echo "NO !!"
The last way is a bit messy, but alot smaller then the first one,
but here's yet another way that's small and less messy:
ls /usr/local/bin/ 1>/dev/null 2>&1 && cp file /usr/local/bin/ || echo "NO !!"
That might look really weird at first sight, but it's easy if you break it
down and look at it:
ls /usr/local/bin/ <<==== lists /usr/local/bin/
1>/dev/null <<==== sends the contents of the listing to 'the black hole'
2>&1 <<==== sends any errors the same way... to 'the black hole'
(same thing as to say 2>/dev/null)
&& <<==== if the first command worked, we will go on here.
cp file /usr/local/bin/ <<==== copy file to /usr/local/bin/
|| <<==== if the first command didn't work...
we go on here instead.
echo "NO !!" <<==== what it says ... say NO !!
as this:
If `ls` can list /usr/local/bin/ next command can be executed, OR if not
it will echo "NO !!", and all listings/errors are being sent to /dev/null
the 'black hole' of a UNIX/Linux.
-------------------------------------------------------------------------------
To prevent that a script is being executed more the once at the same time
for some reason you may wanna let the script make a 'lock' file.
This is very easy to do:
#!/bin/bash
ls script.lock 1>/dev/null 2>&1 && exit 0 && echo "lockfile detected"
> script.lock
echo "Here is where the script should be"
rm -f script.lock
exit 0
Here we first check if there is a lockfile, and if there is we terminate
the script and say that a lockfile was detected.
If there is no lockfile, we create one and start to execute the rest of the
script.
At the end of the script we remove the lockfile, so that the script can
be executed again.
All this is just to prevent the same script to be run twice at the same time,
which can be a good thing if your script does something that cant be done
twice at the same time, as mounting a hard drive/cd-rom, using sound or
anything like that.
Another neat little trick is if you from within a script are going to
create temporary files that you want unique (to not overwrite some other
files anywhere, wherever the script may get executed) you can do like this:
#!/bin/bash
echo "ls" >.tmp.$$
echo "-la" >.tmp2.$$
one=`cat .tmp.$$`
two=`cat .tmp2.$$`
$one $two
rm -f .tmp.$$ .tmp2.$$
This will make a file called .tmp.<pid of script> containing the word "ls",
then it will make a file called .tmp2.<pid of script> containing "-la".
After that it make 2 variables, each one when being called will `cat` one
of the .tmp.* files each.
At the end we have "$one $two" that will work the same as if we had printed:
ls -la
And last we remove the temporary files.
This is useful if your doing a script that requires you to move around alot
of text from one file to another and back, as this example:
#!/bin/bash
sed 's/www/ftp/g' tmp > .tmp.$$
sed 's/com/org/g' .tmp.$$ > .tmp2.$$
sed 's/ /_/g' .tmp2.$$ > .tmp3.$$
mv -f .tmp3.$$ tmp
rm -f .tmp.$$ .tmp2.$$ .tmp3.$$
exit 0
Here we change all www's in a file (tmp) to ftp, then we change all com's
to org, and then all spaces to underscores.
After that we move the fully changed file so it overwrites the original file.
Then removing the temporary files and exit the script.
If you have a good look at it, it's really easy.
Another nice trick is as I showed in the example prior to the last one:
...
one=`cat .tmp.$$`
two=`cat .tmp2.$$`
...
That a variable can hold a command can prove to be useful, like this:
#!/bin/bash
time=`date +%H:%M:%S`
echo "$time" >> log
echo "some input to the log" >> log
sleep 60
echo "$time" >> log
echo "some input to the log a minute later" >> log
exit 0
But, it can hold more then just a command, it can actually *hold* the contents
of a whole file.
Say now that you made a script and have a pretty large readme file, and want
to display that as a 'man page' to the script if the argument `--help`
is used to execute the script, then you can do like this:
#!/bin/bash
one="$1"
help=`cat README`
if [ "$one" = "--help" ]; then
$help | more
...
Ofcorce it would be easier to say:
#!/bin/bash
if [ "$?" = "--help" ]; then
more README
fi
But these examples are just here for illustration so you get the point
of usage for commands and so.
Another trick is, if you wanna hide script/program you can rename it to:
-bash, that way it will look as a normal bash running in the `ps`
(process list), you rename it by doing:
mv script ./-bash
Then execute it like normal ./-bash
Yet another trick, is if you're doing a script where you want each line
of a file as a variable, unlike for that takes each word as a variable.
This can be done like this:
#!/bin/bash
file="$1"
min="0"
max=`cat $file | wc -l`
if [ "$1" = "" ]; then
echo "Usage: $0 <file>"
exit -1
fi
while [ "$min" != "$max" ]; do min=`expr $min + 1`
curline=`head -$min $file | tail -1`
echo $curline
test $min -eq $max && exit 0
done
The `test` is there to make sure that it will end when $min and $max are the
same.
Now this can be done with `for` if you change IFS (described later), but that
is not recomended, especially if you export IFS since that would change the
enviorment and hence screw with the system scripts if they were to be runned
before changing IFS back to normal, but enough about that now, just keep
it somewhere far back in your head, dont change IFS unless you know what
you're doing.
If you dont understand this little script at this point, dont worry, you
will understand it the second time you read this tutorial =)
-------------------------------------------------------------------------------
Now let's take a quick look at arrays in shell scripting.
First off, an array is what it says, it's an array of something,
now, to declare a variable that can hold an array we create it with the
command `declare`, let's make a short example:
alien:~$ declare -a foo=(1 2 3 4 5)
alien:~$ echo ${foo[0]}
1
alien:~$ echo ${foo[1]}
2
alien:~$ foo[1]=bar
alien:~$ echo ${foo[1]}
bar
alien:~$
First of all, to understand the declare command better do `help declare`
at a console and it'll desplay this:
declare: declare [-afFrxi] [-p] name[=value] ...
Declare variables and/or give them attributes. If no NAMEs are
given, then display the values of variables instead. The -p option
will display the attributes and values of each NAME.
The flags are:
-a to make NAMEs arrays (if supported)
-f to select from among function names only
-F to display function names without definitions
-r to make NAMEs readonly
-x to make NAMEs export
-i to make NAMEs have the `integer' attribute set
Variables with the integer attribute have arithmetic evaluation (see
`let') done when the variable is assigned to.
When displaying values of variables, -f displays a function's name
and definition. The -F option restricts the display to function
name only.
Using `+' instead of `-' turns off the given attribute instead. When
used in a function, makes NAMEs local, as with the `local' command.
So here we see that the -a switch to declare makes the variable an array.
So after getting that `declare -a` we declare the variable as an array,
with the array within paranteses.
And then to make use of it, we use the way to write a variable like this:
${ variable name here }
and the number inside the []'s is the number that points to which part of
the array it should use, begining from 0 which is the first.
Let's make another short example:
declare -a foo=(this is another example)
echo "The array (${foo[*]}) has (${foo[0]}) as first, and (${foo[3]}) as last."
The output of this would be:
The array (this is another example) has (this) as first, and (example) as last.
Now, this isn't something you'll use in every day scripting, but it's still
something you should know the existance of, just in case you see it or need
it at some point.
-------------------------------------------------------------------------------
Now here's a less common way of using bash, CGI scripts.
Most people dont assosiate shell scripting with cgi, but it works
just as well as any other language, so here I'd like to to show
you how to make CGI scripts in bash.
-------------------------------------------------------------------------------
Here is the first example which is a simple cgi counter in bash.
A note is that all CGI scripts should be in the servers cgi-bin directory
or any subdirectory there off, unless the server is configured to see
any other directorys as cgi directorys.
-------------------------------------------------------------------------------
#!/bin/bash
test -f date.txt || echo `date "+%B %d %Y"` > date.txt
test -f counter.txt || echo '0' > counter.txt
current=`cat counter.txt`
date=`cat date.txt`
visitor=`expr $current + 1`
echo "$visitor" > counter.txt
echo 'Content-type: text/html'
echo ''
echo '<br>Vitor:'
echo '<br>'$visitor'<br>Since'
echo '<br>'$date'</br>'
-------------------------------------------------------------------------------
Let's take this one line by line here:
First the shell ....
#!/bin/bash
Then we test if there is a file called date.txt, if not then we echo the
current date to it and hence creating it.
test -f date.txt || echo `date "+%B %d %Y"` > date.txt
Then we test if there is a file called counter.txt and if not we echo a 0
to it and so create that one too.
test -f counter.txt || echo '0' > counter.txt
Now we declare the variables, current is the contents of counter.txt.
current=`cat counter.txt`
The date variable is the contents of date.txt.
date=`cat date.txt`
And visitor is the sum of the contents of counter.txt + 1.
visitor=`expr $current + 1`
And then we echo the new increased number to counter.txt.
echo "$visitor" > counter.txt
And here comes the HTML part. the first to line is the 'cgi header'
those should ALWAYS be there:
echo 'Content-type: text/html'
echo ''
Then we move on to the *real* html:
echo '<br>Vitor:'
echo '<br>'$visitor'<br>Since'
echo '<br>'$date'</br>'
The <br> is a linebreak in html
The bash variables have to be *ouside* the 's else they will simply show
up as $visitor or $date litterly, that's why it's made like this:
echo 'text' $variable 'some more text'
So that the text is enclosed with 's, but the variables are between or rather
outside of them.
Anyway, this cgi will create a section that looks like this on a webpage:
----------------
Vitor:
1
Since
May 29 2001
----------------
To add that to a html code you add this tag to your html/shtml page:
<!--#exec cgi="<path to counter>" -->
With the path to the counter it could look like this:
<!--#exec cgi="/cgi-bin/counter/counter.cgi" -->
Not so hard is it ?
-------------------------------------------------------------------------------
Here is another example of a CGI script in bash (actually the second CGI
script I ever made).
-------------------------------------------------------------------------------
#!/bin/bash
method=`echo $QUERY_STRING | awk -F'=' '{print $1}'`
host=`echo $QUERY_STRING | awk -F'=' '{print $2}'`
if [ "$method" = "nslookup" ]; then
echo 'Content-type: text/html'
echo ''
echo '<html>'
echo '<body bgcolor="white">'
echo '<center>'
echo '<br>nslookup '$host' (This might take a second)<br>'
echo '<hr width="100%">'
echo '</center>'
echo '<pre>'
nslookup $host
echo '</pre>'
echo '<center>'
echo '<hr width="100%">'
echo '<br>nslookup compleat'
echo '</center>'
echo '</body>'
echo '</html>'
fi
if [ "$method" = "ping" ]; then
echo 'Content-type: text/html'
echo ''
echo '<html>'
echo '<body bgcolor="white">'
echo '<center>'
echo '<br>ping '$host' (This might take a second)<br>'
echo '<hr width="100%">'
echo '</center>'
echo '<pre>'
ping -c 5 $host
echo '</pre>'
echo '<center>'
echo '<hr width="100%">'
echo '<br>ping compleat'
echo '</center>'
echo '</body>'
echo '</html>'
fi
if [ "$method" = "scan" ]; then
echo 'Content-type: text/html'
echo ''
echo '<html>'
echo '<body bgcolor="white">'
echo '<center>'
echo '<br>Scanning host '$host' (This might take a minute)<br>'
echo '<hr width="100%">'
echo '</center>'
echo '<pre>'
nmap $host
echo '</pre>'
echo '<center>'
echo '<hr width="100%">'
echo '<br>Scan compleat'
echo '</center>'
echo '</body>'
echo '</html>'
fi
-------------------------------------------------------------------------------
Now let's take a look at what that means:
-------------------------------------------------------------------------------
This time it wont be all the lines, but all the new parts:
First the 2 variables:
method=`echo $QUERY_STRING | awk -F'=' '{print $1}'`
host=`echo $QUERY_STRING | awk -F'=' '{print $2}'`
These are made this way because of how the CGI script imports the variables
from a form (I'll come back to this), the $QUERY_STRING variable is
from the webservers enviorment, and so is one of the httpds env variables.
And what you do with the $QUERY_STRING is depending on how you create
your web form .... but as I said I'll get back to that.
Now the rest:
if [ "$method" = "nslookup" ]; then
That was pretty obvious .... if the first feild of $QUERY_STRING (separated
by a =, is "nslookup", then go ahead here:
echo 'Content-type: text/html'
echo ''
Yes the header ....
echo '<html>'
echo '<body bgcolor="white">'
echo '<center>'
echo '<br>nslookup '$host' (This might take a second)<br>'
echo '<hr width="100%">'
echo '</center>'
echo '<pre>'
Create a HTML page ... and then after the <pre> we do the actual center part
of the script:
nslookup $host
Which will resolve the DNS of the host (try the command and see),
And after that we end the html page:
echo '</pre>'
echo '<center>'
echo '<hr width="100%">'
echo '<br>nslookup compleat'
echo '</center>'
echo '</body>'
echo '</html>'
and then end the if statement:
fi
and then the same for the others, just diffent objects at what they should
do, as this was nslookup, the other sections will mnap (portscan) and ping
the host instead.
Now how would a full HTML page look to make use of this cgi script ?
As we this time need input to get the host or IP to scan/ping/nmap.
Well like this:
-------------------------------------------------------------------------------
<html>
<body bgcolor="white">
<center>
<p><font size="+1">Enter host or IP</font></p>
<hr width="100%">
<br>
<form action="http://www.yourdomain.com/cgi-bin/scan.cgi" method="get">
<input type="text" name="scan" value="" size="30">
<input type="submit" value="portscan">
</form>
<p>
<form action="http://www.yourdomain.com/cgi-bin/scan.cgi" method="get">
<input type="text" name="nslookup" value="" size="30">
<input type="submit" value="nslookup">
</form>
<p>
<form action="http://www.yourdomain.com/cgi-bin/scan.cgi" method="get">
<input type="text" name="ping" value="" size="30">
<input type="submit" value="ping -c 5">
</form>
</center>
</body>
</html>
-------------------------------------------------------------------------------
Now what does all this mean ? ....
Well, I wont turn this into a HTML tutorial, but I'll explain this so you
can make use of bash for CGI.
Right to the important HTML part here:
<form action="http://www.yourdomain.com/cgi-bin/scan.cgi" method="get">
<input type="text" name="scan" value="" size="30">
<input type="submit" value="portscan">
</form>
Here we create a form, as in an input feild, which will add it's input
(in a specific way) to the end of the url in action="".
the method is get since we're getting the output of the cgi script.
we name this feild scan so we get the output this way:
?scan=<input>
Where the <input> is what you typed in the input box.
And then we make an "ok" button that says "portscan".
So if you type say 127.0.0.1 and press the portscan button the URL it will
be directed to is this:
http://www.yourdomain.com/cgi-bin/scan.cgi?scan=127.0.0.1
And this "scan=127.0.0.1" will be the $QUERY_STRING enviormental variable.
And so the script is starting to make sense.
-------------------------------------------------------------------------------
Here's a REALLY simple cgi script just for the illustration aswell.
-------------------------------------------------------------------------------
#!/bin/bash
string="Hello World"
echo 'Content-type: text/html'
echo ''
echo '<html>'
echo '<br>'$string'</br>'
echo '</html>'
-------------------------------------------------------------------------------
And the html to call that ..... just a normal hyper link.
<a href="http://www.yourdomain.com/cgi-bin/yourscript.cgi">Link</a>
And that's it.
-------------------------------------------------------------------------------
That's it on the tricks, now let's move on to practical examples so you get
a little bit of feel for how you can use bash to make things easier for you.
===============================================================================
5 - Practical Scripting Examples.
===============================================================================
I'd first like to add a note which you already probably knows:
./ == look in current directory instead of the "PATH".
To give that an example, say now that you have a script in your home
directory called "ls" or "dir", how would you execute that without
getting the contents of the directory ?
well, that's why you use "./" before a name to execute it if it's in the
current directory.
../ == previous directory (one directory further up towards "/" then you are
currently in), this can be used as this, say that you have a script called
"script" in "/home/user/" and you are standing in "/home/user/nice/" and
you don't want to leave the directory but still want to execute the script.
Then you do, "../script" and if you are in "/home/user/nice/blah/" you
you would do, "../../script" ----- "../../" == 2 directory's back.
Get the idea ?
Anyway, now to the practical examples, which are working scripts for
various purposes, to give an idea about what you can do with shell scripting.
New things previously not explained will show up in this section, but
I will explain them as we go along.
Let's start with simple examples and move on to harder parts.
As for first I'll stick to useless scripts =) just for illustration.
Explanation on the scripts follow after them, as usual.
So here we go on that.
-------------------------------------------------------------------------------
#!/bin/bash
one="$1"
something="$2"
if [ "$one" = "" ]; then
echo "Usage: $0 [name] <anything goes here>"
exit 0
fi
function first {
clear
echo "this is a test script !"
echo
echo "name followed on $0 was - $one - "
echo
echo "if you typed anything after the name it was: $something"
echo
}
first
exit 0
-------------------------------------------------------------------------------
Executed without any thing after the script name it looks like this:
alien:~$ ./script
Usage: ./script [name] <anything goes here>
alien:~$
Say that you want to change your shell to /bin/csh and your path to just /bin
(you dont), but just if you would in your: .bash_profile add:
-------------------------------------------------------------------------------
SHELL=/bin/csh
PATH=/bin
export PATH SHELL
-------------------------------------------------------------------------------
Not so hard huh ?
-------------------------------------------------------------------------------
The next thing here is a question that I've heard alot, and that is "how do I
change my command prompt ?".
The command Prompts variable is named PS1 ($PS1)
for a prompt that looks like this:
[alien@localhost alien]$
the contents of the PS1 variable would be this:
[\u@\h \W]\$
All the prompts internal variables starts with a \ (backslash)
useful:
\$ = the prompt ($ for user and # for root)
\d = date
\h = abbreviated hostname (root.host.com would become root)
\H = full hostname
\s = shell type
\t = time
\T = time with seconds
\u = username
\v = shell version (short)
\V = shell version (long)
\w = full path
\W = current directory name
less useful:
\e = erase rest of line .... not very useful
\n = new line ... not very useful
\r = whatever comes after \r is displayed before the first character.
A couple of examples would be:
*BSD like.
PS1="\u: \w> "
DOS like.
PS1="C:\w > "
RedHat like.
PS1="[\u@\h \W]\$ "
Init 1 like.
PS1="\s-\v \$ "
How do I use colors in the prompt ?
To use colors in the prompt you need to be familiar with the escape sequence
color codings, those are as follows:
reset = ^[[0m
flashing = ^[[5m
black = ^[[0;30m
red = ^[[0;31m
green = ^[[0;32m
yellow = ^[[0;33m
blue = ^[[0;34m
magenta = ^[[0;35m
cyan = ^[[0;36m
white = ^[[0;37m
highblack = ^[[1;30m
highred = ^[[1;31m
highgreen = ^[[1;32m
highyellow = ^[[1;33m
highblue = ^[[1;34m
highmagenta = ^[[1;35m
highcyan = ^[[1;36m
highwhite = ^[[1;37m
bg-white = ^[[47m
bg-magenta = ^[[45m
bg-blue = ^[[44m
bg-red = ^[[41m
bg-black = ^[[40m
bg-green = ^[[42m
bg-yellow = ^[[43m
bg-cyan = ^[[46m
Important to know is that the leading `^[` is NOT 2 characters, it's ONE
control character that that takes up the space of 2 characters, or is
described by 2 characters, if you have a real ^[ and you try to delete the
[ do it it will delete both the [ and the ^ at the same time.
------------------------------------------------
Not really sure where to put this note but here,
^[[<number>G
Puts the cursor at column <number>, as this:
echo -n "Starting myprog:" && echo -e "^[[50G OK" || echo -e "^[[50G FAILD"
------------------------------------------------
So how do you get a real control character ?
Either you use the very old line editor 'ed' and press Ctrl+[ to get the
control character (ed commands are described at the end of this tutorial),
or you can use 'emacs' or the text editor 'joe'.
To get control characters in emacs you press ^Q and ^<what you want>,
as if you want a ^[ you press ^Q^3, and then ^X^S^X^C to save and quit.
To get control characters in joe you press ` and then the character to make
a control character, in this case [, when you do this in joe the ^[
should look like a bold [.
To save and quit in joe you press: Ctrl+K followed by Ctrl+X
It's only the ^[ that is a control character the rest is normal ['s and
numbers and so on.
Don't forget to enclose all your colors codes in \[ \], this means that
^[[0;31m (red) would be written as \[^[[0;31m\].
Where do I write this and how does an example look ?
You add this in your ~/.bash_profile, you can put it at the end of the file.
Some examples are:
[ highblue-user red-@ highblue-host green-dir ] highblue-$
PS1="\[^[[1;34m\u^[[0;31m@^[[1;34m\h ^[[0;32m\W^[[0m\]^[[1;34m\$ \[^[[0m\] "
highblue-user highwhite-: highblue-path >
PS1="\[^[[1;34m\]\u\[^[[1;37m\]: \[^[[0;31m\]\w \[^[[0m\]> "
(you can not cut and paste these examples without editing the ^['s to real
control characters, and know that a color prompt is almost always buggy)
-------------------------------------------------------------------------------
The next thing to take up is how to set aliases and to change system variables.
An alias is set in the ~/.bashrc file, if you use /bin/bash else, it's most
likely in your .`shell type`rc as .zshrc .csh .tcsh etc.
An alias means that you can make a short command for a longer command,
as the alias `l` can mean `ls` and the alias `la` can mean `ls -la`, and
so on, an alias is written like this (also a list of useful aliases):
alias rm='rm -i'
alias mv='mv -i'
alias cp='cp -i'
alias s='cd ..'
alias d='ls'
alias p='cd -'
alias ll='ls -laF --color'
alias lsrpm='rpm -qlp'
alias lstgz='tar -tzf'
alias lstar='tar -tf'
alias mktgz='tar -cfz'
alias untar='tar -vxf'
alias untgz='tar -vzxf'
rm will now ask before removing anything.
mv will now ask before overwriting anything.
cp will now ask before overwriting anything.
s will now work as cd ..
d will now work as ls.
p will now work as cd - (cd - == takes you to your last dir ie.
you are in /usr/local/bin/ and does a cd /, if you from here wanna go back
to /usr/local/bin/ you simply type `cd -`, or now just `p`.)
ll will do a ls -la with colors and ending * after executable files and ending
an ending / after dirs.
lsrpm will list the contents (where the files will end up if you install it) of
any rpm file.
lstgz will list the contents of a .tar.gz or .tgz file.
lstar will list the contents of a plain .tar file.
mkgz will make a tgz archive (mktar archive.tgz directory).
untar will untar a .tar file.
untgz will unzip and untar a .tar.gz or a .tgz file.
There is more alias like things you can set in the ~/.bashrc file, like
smaller functions that works as aliases, like this:
function whichrpm { rpm -qf `'which' $1`; }
typing "whichrpm <command>" at a prompt will name the rpm file it came with.
the rpm -qf command works like this:
alien:~$ rpm -qf /usr/bin/dir
fileutils-4.0i-1mdk
alien:~$
And the function works like this:
alien:~$ whichrpm dir
fileutils-4.0i-1mdk
alien:~$
function - tells bash that it's function.
whichrpm - user defined name of the function.
{ / } - starts/ends the function
rpm -qf - command
` command quote
' precise quote
which - command to locate a file in your path
$1 - first argument after the function (the command after the function name
when you execute it).
; - end line
function whichrpm { rpm -qf `'which' $1`; }
So when you execute this, the system will think.
aaah, a function within those {}'s, which I should call for when I hear
the word "whichrpm", and what's after that word ($1) will be used as
argument to "which", and what that returns will be used after "rpm -qf".
which works like this:
alien:~$ which dir
/usr/bin/dir
alien:~$
So "`'which' $1`" (when executed with the word 'dir') returns "/usr/bin/dir",
and so the whole function will finally execute: rpm -qf /usr/bin/dir
-------------------------------------------------------------------------------
Now more about the files in /etc, here you cant be user anymore,
to edit the files in /etc requires you to be root.
Fist here I'm going to talk about the /etc/crontab configuration file.
-------------------------------------------------------------------------------
The /etc/crontab is the global system file for cron jobs.
cron is short for chronological, and as the name tells it's doing things
in a chronological order, as you can tell it to run a script or a program
once every 1 minutes, or you can tell it to run something annually, and
anything in between.
On RedHat like systems you have the dirs:
/etc/cron.daily/
/etc/cron.hourly/
/etc/cron.monthly/
/etc/cron.weekly/
Any script or program that lives in those files will execute by the last
name of the file, as if you put a script in /etc/cron.weekly/, the script
will execute weekly.
The /etc/crontab looks like this:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
The SHELL determens what shell that should be used to execute the things
in the crontab.
The PATH determens what directory's it should look in for commands/programs
if no other specific path is given to a program, command or script.
The MAILTO variable determens to what user cron should send mails to on errors.
And the HOME variable determens crons root/home/base directory.
The first 5 fields determens when to run a job, here's what they mean:
Field 1: minutes (0-59)
Field 2: hours (0-23)
Field 3: day of month (1-31)
Field 4: month (1-12 - or names)
Field 5: weekday (0-7 - 0 or 7 is Sun, or use names)
The next field is the user that owns the execution process.
Then we have run-parts, and after that the file to execute.
(if the file to execute is a dir, it will execute everything in it)
To use the crontab as a user (root included) simply type: crontab -e
This brings you to a VI like editor (see VI commands later in this tutorial).
Say now that you have a script /home/user/check.sh that you wanna run
every 5'th minute. then you type "crontab -e"
Press 'Esc' followed by 'o' to get to "insert" or "edit" mode.
In there make the following line:
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /home/user/check.sh --flag
Then press 'Esc' followed by ':' and then type 'wq' followed by enter to
write/save and, quit the file, and that's it.
When you run crontab as user you don't have to specify what user that should
own the process, "* * * * * file" should be enough.
Another way of writing:
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /home/user/check.sh --flag
Is this:
0-59/5 * * * * /home/user/check.sh --flag
That means do this (/home/user/check.sh --flag) from 0-59 with 5 as an
intervall.
This means that:
* 0-23/2 * * * /home/user/check.sh --flag
Would run the same script every other hour.
Not very hard is it ?
-------------------------------------------------------------------------------
Then we have the /etc/fstab is a list of the HD partitions the system
should mount as what when the system boots.
This may look like this:
/dev/hda1 / ext2 defaults 1 1
/dev/hda3 none swap sw 0 0
/dev/hda4 /home ext2 defaults 1 2
/dev/hda6 /tmp ext2 defaults 1 2
/dev/hdc1 /windows vfat defaults 0 0
/dev/fd0 /mnt/floppy auto noauto,nosuid 0 0
/dev/hdb /mnt/cdrom auto noauto,ro 0 0
Fist it's the HD partition, then (a few tabs in) the mount point (where the
eventual contents of the HD partition should end up), then what file system
the partition has, further is if it should be mounted by default etc.
and the last 2 numbers is fs_freq and fs_passno (see the man page for fstab).
The possible HD partitions you have to find for your self or know...
a tip is to go over the HD's with fdisk, and check for free space.
The possible mount points is only limited by your imagination, though
there must always be a /
A good disk usage should have these partitions:
/ 5%
/usr 30%
/home 30%
/tmp 10%
And 25% over for other partitions, like /sources, or whatever.
The possible and supported file systems are currenty:
minix,ext,ext2,xiafs,msdos,hpfs,iso9660,nfs,swap,vfat, and perhaps ntfs
The possible mount options are:
sync,user,noauto,nosuid,nodev,unhide,user,noauto,nosuid,exec,nodev,ro etc.
see the man mount page.
So say that you are going to add another cdrom that you want user to be able
to mount, and the cdrom is on /dev/hdd, then the line to add would look like
this (make sure you have the mount point dir, like here you have to
mkdir /cdrom):
/dev/hdd /cdrom auto noauto,user,ro 0 0
And that's about it for the /etc/fstab
-------------------------------------------------------------------------------
Now I'd like to explain one of the very important files, the /etc/profile file.
In this file is the Global profile settings, that will apply for all users.
Fist in this file we should have the PATH variable.
The directory's in the PATH is the directory's the system will look in if you
type a command, for that command to execute it.
Say now that your path looks like this:
PATH="$PATH:/usr/X11R6/bin:/bin"
And you type "ls", then the system will first look in /usr/X11R6/bin if it can
find any file named "ls", and if it doesn't find it there, it will look in /bin,
and if it finds it there it will execute it.
The most common places on a system to store commands and programs is in these
directory's:
/usr/X11R6/bin
/bin
/sbin
/usr/bin
/usr/sbin
/usr/local/bin
/usr/local/sbin
A path with all those directory's in it would look like this:
PATH="$PATH:/usr/X11R6/bin:/bin:/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/u
sr/sbin"
The next thing in there can/should be the PS1 (the prompt), I've already
taken up how to customize the prompt, so no need to do that again.
Then (at least in RedHat like systems) we have this:
[ "$UID" = "0" ] && {
ulimit -c 1000000
} || {
ulimit -c 0
}
This says: if the UID of the user is 0 (root) then do: ulimit -c 1000000
or if that doesn't work, do: ulimit -c 0.
Then we have an if statement about umask on the user...
After that we define some system variables, where after we export them.
Then we load all the .sh scripts in /etc/profile.d/
And that's it, in that file.
This is an important file if you wanna add any system variables, or if you
want to change anything globally for the whole system.
-------------------------------------------------------------------------------
Now on to the /etc/hosts.allow and /etc/hosts.deny files.
Those hosts who are in hosts.allow are always allowed to connect to the system
under the condition that they have valid login and password ofcorse.
Those hosts who are in hosts.deny can never establish a lasting connection
to your system, even if they have a valid login and password.
If you don't want anyone to connect to your computer at all, you simply add
the following to /etc/hosts.deny:
ALL: ALL
And this to /etc/hosts.allow:
ALL: LOCAL
Or if you have a network, you may wanna add this in /etc/hosts.allow:
ALL: LOCAL, 192.168.1.
Where 192.168.1. is your network call C network.
/etc/hosts.allow and /etc/hosts.deny understands the following wildcards:
ALL The universal wildcard, always matches.
LOCAL Matches any host whose name does not contain a dot character.
UNKNOWN Matches any user whose name is unknown.
KNOWN Matches any user whose name is known.
PARANOID Matches any host whose name does not match its address.
Read man hosts.allow or man hosts.deny (should be the same man file), to find
out more about this.
-------------------------------------------------------------------------------
Next up is the /etc/inputrc file, which contains breaf keyboad confirurations.
If you want to something like Ctrl+W or something to a function of any kind
here is the place to do that.
The example from the file looks like this:
# Just a little exemple, how do you can configure your keyboard
# If you type Control-x s it's add a su -c " " around the command
# See the info files (readline) for more details.
#
# "\C-xs": "\C-e\"\C-asu -c \""
This would mean that if you want to add say: Ctrl+W to add the command
`time` before another command you would do:
"\C-w": "\C-e\ \C-atime \
Another example would be, if you want to add: Ctrl+W Q to add: echo "<command>"
around the <command> you would do:
"\C-wq": "\C-e\"\C-aecho \""
This means that if you type 'word' and then press Ctrl+W followed by Q you
will end up with: echo "word", pretty handy.
You can also add a .inputrc in your home dir with the same functions,
but only for that user.
Just make sure you dont overwrite some other function, test the Ctrl+<key(s)>
function that you wanna use so they dont already do something.
If you want to bind keys to functions or characters, this is not the place
to do that, then you need to find your keymap like this one:
/usr/lib/kbd/keymaps/i386/qwerty/se-latin1.kmap.gz
gunzip it, edit it and then zip it up again.
I will not explain how to edit a keymap here, but it's not that hard,
just read the contnts of the unziped keymap a few times and use the
power of deduction.
-------------------------------------------------------------------------------
The /etc/passwd holds the login information which looks something like this:
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
alien:x:500:500:Me:/home/alien:/bin/bash
user:x:501:501::/home/user:/bin/csh
You are looking on 7 accounts, nameley: root, bin, daemon, adm, lp, shutdown,
alien and user.
each of the lines have 7 feilds separated by ':'.
The fields from left to right are:
1 login-name
2 encrypted-password (this field contains only 'x' if there is an /etc/shadow)
3 uid (user id)
4 gid (group id)
5 user-information
6 home-directory
7 shell-type
If you make an account by hand in the /etc/passwd file, put a '*' in the
encrypted-password field and use the `passwd` command to set the password.
-------------------------------------------------------------------------------
The /etc/shadow file, if this file exists, this is where the real
encrypted passwords are located, this file can only be read by the super-user
(root), and it looks like this:
root:$1$UrbUdguK$yrO3U/dlwKC5K3y2ON/YM.:11056:0:21:7:::
bin:*:11056:0:99999:7:::
daemon:*:11056:0:99999:7:::
adm:*:11056:0:99999:7:::
lp:*:11056:0:99999:7:::
shutdown:$1$hu86lnLIhnklY8ijnHui7.nn/jYg/mU:11056:1:365:14:::
alien:$1$vf3tGCFF$YRoFUgFDR8CVK6hHOwU/p0:11056:0:50:14:31::
user:$1$asd8kiLY76JNdskDkj97kMiyBujy/jD:11074:2:100:14:3::
(I've changed the characters in the encrypted-password, so they are not valid)
The manual page (man 5 shadow) tells the following about the 9 fields:
Login name
Encrypted password
Days since Jan 1, 1970 that password was last changed
Days before password may be changed
Days after which password must be changed
Days before password is to expire that user is warned
Days after password expires that account is disabled
Days since Jan 1, 1970 that account is disabled
A reserved field
If anyone knows what the last field (after the final ':') is reserved for ...
please drop me a mail.
Read the lines from the files, and compare them with what the 9 fields
mean, and see if you can make out how the accounts for each user is set up.
-------------------------------------------------------------------------------
Now the /etc/motd file.
The /etc/motd contains whatever you want to display to the user
that logs into the system, this can be a set of rules for your system,
or some ascii graphics or whatever you want.
-------------------------------------------------------------------------------
And now the /etc/skel/ which is a dir and contains the basic files
that will be given to any new user account.
Say that you add a file called, /etc/skel/.ircrc then all new useraccounts
that are added will have a ~/.ircrc file in there home directory.
-------------------------------------------------------------------------------
And last the /etc/issue and /etc/issue.net file.
On most systems there is only an /etc/issue file that works as both
/etc/issue and /etc/issue.net, the issue file holds the information
or rather text that is displayed to the user just before the
login prompt, usually it is the system specifications, like operating system
version and things like that.
The /etc/issue (if there is any /etc/issue.net) is the issue file for the
local users, and the /etc/issue.net is for users that logs in
from a remote host.
-------------------------------------------------------------------------------
There is alot more in the /etc directory, but what I've written this
far is about what you need to customize your system to your needs.
===============================================================================
7 - Networking.
===============================================================================
Linux is known to be one of the best networking operating systems in the
world, perhaps even THE best, unfortionally it's not the easiest OS to
set up a good network in, but I hope that this section will make
exclamation marks out of some question marks.
-------------------------------------------------------------------------------
The first thing you need to do networking is 2 computers and
network cards attached with a crossed network cable, or connected via a hub,
with normal network cable (doh?).
The next step is to make sure the network cards work properly.
Make sure you have the networking support compiled into the kernel, you need
to have the following checked in the kernel (example is from the Linux 2.2.14
kernel, using `make menuconfig`, you can read more about how you
compile/recompile your kernel in /usr/doc/HOWTO/Kernel-HOWTO):
General setup --->
[*] Networking support
Networking options --->
[*] Kernel/User netlink socket
[*] Network firewalls
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP: advanced router
[*] IP: firewalling
[*] IP: transparent proxy support
[*] IP: masquerading
[*] IP: ICMP masquerading
[*] IP: aliasing support
<*> IP: Reverse ARP
[*] IP: Allow large windows (not recommended if <16Mb of memory)
Network device support --->
[*] Network device support
Ethernet (10 or 100Mbit) --->
[*] Ethernet (10 or 100Mbit)
(In here find your network card and check it.)
Filesystems --->
[*] /proc filesystem support
Now it's almost time to start the nameserver, but first you wanna add the
nameserver to your /etc/resolv.conf so you have any use of it.
Open /etc/resolv.conf and at the top of it add:
nameserver 10.0.0.1
and leav the rest of the file entry's as they are if there is any, then
save and quit that.
And now it's time to start the nameserver.
To be sure that everything works normally, do these commands:
/usr/sbin/named
/usr/sbin/ndc restart
And then type `nslookup`, that should look like this:
root:~# nslookup
Default Server: main.bogus.com
Address: 10.0.0.1
>
If you get that, just type exit at the ">", and then add the following lines
to /etc/rc.d/rc.local
if
ps aux | grep named | grep -v grep >/dev/null ; then
echo >/dev/null
else
/usr/sbin/named
/usr/sbin/ndc restart
fi
This will check if you have a named running, and if not, it will start it,
note that this is not the 100% correct way to do it, but it's by far they
most lazy way to do it, and it works.
-------------------------------------------------------------------------------
That was the basics of making a network at home and setting up a nameserver.
I hope it's enough so that anyone can set up a little network at home.
===============================================================================
8 - The Init and system scripts.
===============================================================================
In this section I will cover the system V init, which is the most used
init in Linux.
Beside the Syst V inti, there are also the BSD init, which is used by
Slackware and Debian and in some smaller distributions of Linux.
The rest, as far as I know, uses the Syst V init.
There are not so much difference of the two, I'll try to cover the
differences later.
The example and files here are taken from SysVinit-2.78-6 & initscripts-5.27-37
which is compatible in some ways with the BSD init, I'll come back to that
later.
So here we go:
-------------------------------------------------------------------------------
The basic Syst V init comes with the following commands & devices:
/dev/initctl This is the init controll device.
/sbin/halt This is to shut down the system.
/sbin/init This is to change the init runlevel.
/sbin/killall5 This will kill everything but the script that runs it.
/sbin/pidof This will get the PID of a Process name.
/sbin/poweroff This will power down the system.
/sbin/reboot This will reboot the system.
/sbin/runlevel This will tell the init runlevel.
/sbin/shutdown This will shut down the system.
/sbin/sulogin This is the single user mode login.
/sbin/telinit This is the init process control initialization.
/usr/bin/last This shows who was in the system last.
/usr/bin/lastb This is about the same as last.
/usr/bin/mesg This is to toggle writeble mode on your tty.
/usr/bin/utmpdump This dumps a file for utmp (this lacks documentation)
/usr/bin/wall This sends a message to all ttys.
And then the init needs the following extra files/dirs and commands from
the initscripts package:
/bin/doexec This lets you run a program under another name.
/bin/ipcalc This lets you manipulate IP addresses.
/bin/usleep This sleeps for microseconds.
/etc/X11/prefdm This is the display manager preferrence file for X.
/etc/adjtime This is the Kernel Clock Config file.
/etc/init.d BSD init compatibilety directory.
/etc/initlog.conf This is the initlog configuration file.
/etc/inittab This is the main init configuration file.
/etc/modules This is where the kernel loads modules from at boot.
/etc/ppp/ip-down This is a script for dialup internet connections.
/etc/ppp/ip-up This is a script for dialup internet connections.
/etc/profile.d/inputrc.csh Shell Key bindings for csh and tcsh.
/etc/profile.d/inputrc.sh Shell Key bindings for sh and bash.
/etc/profile.d/lang.csh Language files - i18n stuff for csh and tcsh.
/etc/profile.d/lang.sh Language files - i18n stuff for sh and bash.
/etc/profile.d/tmpdir.csh Set temporary directory for csh and tcsh.
/etc/profile.d/tmpdir.sh Set temporary directory for sh and bash.
/etc/rc.d/init.d/functions Functions for scripts in init.d
/etc/rc.d/init.d/halt Runlevel 0 (shutdown/halt) script.
/etc/rc.d/init.d/kheader Script to regenerate the /boot/kernel.h file.
/etc/rc.d/init.d/killall Script to make sure everything is shut off.
/etc/rc.d/init.d/mandrake_everytime Mandrake specific stuff.
/etc/rc.d/init.d/mandrake_firstime Mandrake post install stuff.
/etc/rc.d/init.d/netfs Mounts network filesystems.
/etc/rc.d/init.d/network Bring up/down networking.
/etc/rc.d/init.d/random Script to help random number generation.
/etc/rc.d/init.d/rawdevices Device stuff for applications such as Oracle.
/etc/rc.d/init.d/single Single user script (runlevel 1)
/etc/rc.d/init.d/sound Launch sound.
/etc/rc.d/init.d/usb Launch USB support.
/etc/rc.d/rc.local Boot time script, (like autoexec.bat in DOS).
/etc/rc.d/rc.modules Bootup script for modules.
/etc/rc.d/rc.sysinit Main system startup script.
/etc/rc.d/rc0.d/S00killall Runlevel 0 killall script link.
/etc/rc.d/rc0.d/S01halt Runlevel 0 halt script link.
/etc/rc.d/rc1.d/S00single Runlevel 1 single script link.
/etc/rc.d/rc2.d/S99local Runlevel 2 local script link. (rc.local)
/etc/rc.d/rc3.d/S99local Runlevel 3 local script link. (rc.local)
/etc/rc.d/rc4.d Runlevel 4 directory.
/etc/rc.d/rc5.d/S99local Runlevel 5 local script link. (rc.local)
/etc/rc.d/rc6.d/S00killall Runlevel 6 killall script link.
/etc/rc.d/rc6.d/S01reboot Runlevel 6 reboot script link.
/etc/rc.local BSD init compatibilety file.... ?
/etc/rc.sysinit BSD init compatibilety file.... ?
/etc/rc0.d BSD init compatibilety directory.
/etc/rc1.d BSD init compatibilety directory.
/etc/rc2.d BSD init compatibilety directory.
/etc/rc3.d BSD init compatibilety directory.
/etc/rc4.d BSD init compatibilety directory.
/etc/rc5.d BSD init compatibilety directory.
/etc/rc6.d BSD init compatibilety directory.
/etc/sysconfig/console Directory for console stuff, like the keymap.
/etc/sysconfig/init Basic init boot configurations.
/etc/sysconfig/network-scripts/ifcfg-lo Network config for localhost.
/etc/sysconfig/network-scripts/ifdown Turning off interfaces script.
/etc/sysconfig/network-scripts/ifdown-post Post stuff for ifdown.
/etc/sysconfig/network-scripts/ifdown-ppp Turning off ppp.
/etc/sysconfig/network-scripts/ifdown-sl Turning off SLIP.
/etc/sysconfig/network-scripts/ifup Turning on interfaces script.
/etc/sysconfig/network-scripts/ifup-aliases Turning on alias interfaces.
/etc/sysconfig/network-scripts/ifup-ipx Turning on IPX.
/etc/sysconfig/network-scripts/ifup-plip Turning on PLIP.
/etc/sysconfig/network-scripts/ifup-post Post stuff for ifup.
/etc/sysconfig/network-scripts/ifup-ppp Turning on ppp.
/etc/sysconfig/network-scripts/ifup-routes Turning on routes.
/etc/sysconfig/network-scripts/ifup-sl Turning on SLIP.
/etc/sysconfig/network-scripts/network-functions Functions for the scripts.
/etc/sysconfig/rawdevices Raw device bindings.
/etc/sysctl.conf System Control configurations.
/sbin/consoletype This prints the console type.
/sbin/getkey Prints the key strokes....
/sbin/ifdown Application for the previous config files.
/sbin/ifup Application for the previous config files.
/sbin/initlog Logs msgs and events to the system logger.
/sbin/installkernel Installs a kernel (not for manual use).
/sbin/minilogd * Totally lacking documentation.
/sbin/netreport Reports changes of the network interface.
/sbin/ppp-watch Application used by ifup-ppp.
/sbin/service Can send commands to all services etc.
/sbin/setsysfont Sets the system font.
/usr/bin/listhome Lists the users home directorys.
/usr/sbin/detectloader Detect the current boot loader.
/usr/sbin/supermount Automatic mount/umount application.
/usr/sbin/sys-unconfig System reconfiguration tool.
/usr/sbin/usernetctl User Network interface control application.
/var/log/wtmp Previously logged in users entrys.
/var/run/netreport Directory for the netreport application.
/var/run/utmp Currently logged in users entrys.
So what do you really need to know of all that ?
Well, here's the simple basics of how it works and what you need to remember.
The /etc/inittab is already explained.
-------------------------------------------------------------------------------
Here is how the runlevels works:
The Runlevel can be one of 1 to 6 and the number means this:
0 - halt
1 - Single user mode
2 - Multiuser, without NFS
3 - Full multiuser mode
4 - Unused
5 - X11
6 - reboot
You change the runlevel with the `init` command, so say that you are
int runlevel 3 and you wanna go to single user mode for some reason,
then you can do: init 1
In a single user mode you can only be one user, root.
And in a single user enviorment you can't do networking and
other tasks, the runlevel 1 is meant to be there for system maintenence.
The two mostly used runlevels as default is 3 and 5.
Mandrake and RedHat etc. uses Runlevel 5 as default, and so they
start up with a GUI in X Windows.
Typing init 0 will shut down the system, and typing runlevel 6 will
reboot the system.
-------------------------------------------------------------------------------
What determes what the various runlevels actually start at boot time
is what is in there respective directory:
Runlevel 0: /etc/rc.d/rc0.d/
Runlevel 1: /etc/rc.d/rc1.d/
Runlevel 2: /etc/rc.d/rc2.d/
Runlevel 3: /etc/rc.d/rc3.d/
Runlevel 4: /etc/rc.d/rc4.d/
Runlevel 5: /etc/rc.d/rc5.d/
Runlevel 6: /etc/rc.d/rc6.d/
-------------------------------------------------------------------------------
So, here say that you wanna stop your web server from starting at boot time.
The first thing you wanna do is to find out what runlevel you are in, that
you do with the runlevel command like this:
alien:~$ runlevel
N 3
alien:~$
This means that you are in runlevel 3.
So from here go to /etc/rc.d/rc3.d/ which is the directory for runlevel 3.
alien:~$ cd /etc/rc.d/rc3.d/
alien: /etc/rc.d/rc3.d/ $
Here you find the file that starts the webserver (this file is usually
called httpd with a character and a number infront of it (I'll explain the
character and the numbers soon), so list the contents of the current
directory and find it, or just do like this:
alien: /etc/rc.d/rc3.d/ $ ls -l *httpd
lrwxrwxrwx 1 root root 15 Dec 5 06:14 S85httpd -> ../init.d/httpd
alien: /etc/rc.d/rc3.d/ $
This says that S85httpd is a link to /etc/rc.d/init.d/httpd
(../init.d/ if you're standing in /etc/rc.d/init.d/ mean /etc/rc.d/init.d/)
So just remove the link like this:
alien: /etc/rc.d/rc3.d/ $ rm -f S85httpd
alien: /etc/rc.d/rc3.d/ $
And that's how you stop something from starting with the runlevel.
-------------------------------------------------------------------------------
Now, if you rather would have something more start with the runlevel
at boot time you do like this:
You make a simple script that starts what you wanna have started and
put it in /etc/rc.d/init.d/.
Say that your scripts name is "mystart", you are in runlevel 3 and you have
made your script executable (chmod a+x mystart), and you have it
in your own home directory, then you do like this:
alien: ~$ cp mystart /etc/rc.d/init.d/
alien: ~$ cd /etc/rc.d/rc3.d
alien: /etc/rc.d/rc3.d/ $ ln -s ../init.d/mystart Z00mystart
alien: /etc/rc.d/rc3.d/ $
And that's all of that.
So now, what does the Z00 in Z00mystart or S85 in S85httpd mean ?
Well, as the system starts it will read file after file in it's runlevels
directory in alphabetical order, so to get them to start in a preticular
order, the link names are made to determen that order.
So the later in the alphabet the first character is the later it will boot,
and the same for for the number, the higher number the later it will start.
So A00something will start before A01something
And Z99something will start later then X99something and so on.
To get something to start at boot time you can also add it as a command
in the /etc/rc.d/rc.local (or for some systems /etc/rc.local) file.
That file is meant to be used for single commands and not to start up
major things like a server etc.
Always try to load things with the actual runlevel which is the more correct
way, rather then adding them to the rc.local file
-------------------------------------------------------------------------------
So what's the difference between the BSD init and the System V init ?
The only thing that differs them that you need to rememer is that they
store the startup scripts in different places.
The startup scripts for the BSD init is mainly in the following places:
/etc/rc0.d/
/etc/rc1.d/
/etc/rc2.d/
/etc/rc3.d/
/etc/rc4.d/
/etc/rc5.d/
/etc/rc6.d/
/etc/rc.boot/
/etc/rcS.d/
/etc/init.d/
/etc/rc.d/rc0.d/
/etc/rc.d/rc1.d/
/etc/rc.d/rc2.d/
/etc/rc.d/rc3.d/
/etc/rc.d/rc4.d/
/etc/rc.d/rc5.d/
/etc/rc.d/rc6.d/
/etc/rc.d/init.d/
#!/bin/sh
# example Example init script that would load 'daemon'
#
# Version: @(#) /etc/rc.d/inet.d/example 0.01 19-Feb-2001
#
# Author: Billy (Alien), <alien@ktv.koping.se>
#
. /etc/rc.d/init.d/functions
function status() {
ps aux | grep daemon &&
echo "Daemon is running." ||
echo "Daemon is not running."
}
case "$1" in
start)
# Check if daemon is in our path.
if `which daemon` > /dev/null; then success || failure; fi
echo -n "Starting Daemon"
daemon
echo
;;
stop)
# Check if daemon is in our path again.
if `which daemon` > /dev/null; then success || failure; fi
echo "Stopping Daemon"
killall -15 daemon
;;
status)
echo "Status of Daemon:"
status
;;
reload)
echo "Restarting Daemon."
killall -1 daemon
;;
restart)
if `which echo` > /dev/null; then success || failure; fi
$0 stop
$0 start
;;
*)
echo "Usage: $0 start|stop|restart|status"
exit 0
esac
-------------------------------------------------------------------------------
A note is that the success and failure functions/commands come from
the /etc/rc.d/init.d/functions file, which may not be present in all
distributions of Linux, since it as far as I know only comes with
RedHat and Mandrake.
-------------------------------------------------------------------------------
The inits main configuration file is the /etc/inittab file, here is where
you set which runlevel you you wanna have, and how many consoles you want
etc, so here we go:
The line where you actually set the runlevel looks like this (here runlevel 3):
id:3:initdefault:
Most RedHat like systems have runlevel 3 or 5 as default, but if you don't
have any networking, you may find it better to change to runlevel 2.
Next in this file should be the system initialization.
si::sysinit:/etc/rc.d/rc.sysinit
This line tells the system the path to the rc.sysinit where it loads
alot in the system, as system clock, sets the hostname, and
performs a number of checks.
Next in line is this:
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
This tells the system where to load the programs and daemons it should load
for the runlevel it's in.
Say that we are in runlevel 3 (Default) then it looks at this line:
l3:3:wait:/etc/rc.d/rc 3
And there after goes to load all what's in /etc/rc.d/rc3.d/
(rc3.d or any rc?.d contains links to the real files or scripts
that's located in /etc/rc.d/init.d, so if you wanna add something to
your runlevel, just look how they have done it and do it in a similar fashion.
and make sure to not start any network dependent application before the
network starts and so on...)
Then it comes some other various stuff as trap the Ctrl+Alt+Del etc.
After this comes the tty's (Terminal Types), and there locations.
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
If you wanna add some more you can add like this:
8:2345:respawn:/sbin/mingetty tty8
9:2345:respawn:/sbin/mingetty tty9
10:2345:respawn:/sbin/mingetty tty10
11:2345:respawn:/sbin/mingetty tty11
And leav tty7 reserved for X-windows.
Last in the file should only be some line about xdm and it's location,
this is if you have xdm installed...
-------------------------------------------------------------------------------
And if you have read the tutorial to this point you shouldent need any real
explanation of this script.
If you still dont understand how the init scripts work, read the
scripts in your system and try to understand them.
And also read this section about the init and the init scripts again.
===============================================================================
9 - Basic Linux/UNIX commands and operations.
===============================================================================
This section is about Linux and UNIX basic commands and operations, and some
other explanations and tricks, since this is not a command bible,
I'll explain each command breafly, with alot of help from the
man pages and the --help argument (let's all thank the maker for cut & paste).
Then again, I've seen files that have claimed to be UNIX command bibles
that are even breafer and hold less commands... though most of the authors
of those seems to be totally uncapeble of handling a UNIX and cant even spell,
one of the worst examples I've seen was something like this:
"The UNIX bible, in this phile is all the UNIX commandz j00 need"
And after that was a list of commands without arguments... needless to say
is also that 99% of all UNIX commands were missing.
Anyway, enough of me making fun of those people now, and on with the tutorial.
(Which isn't a UNIX command bible, just a note)
I will refer to "*nix" here, and that means any sort of UNIX system,
Linux, BSD, Solaris, SunOS, Xenix and so on included.
------------------------------------------------------------------------------
Here are the basic *nix commands, with breaf explanations.
------------------------------------------------------------------------------
adduser
Syntax: adduser [arguments] <user>
And can be used with the following arguments:
-u uid
-g group
-G group,...
-d home directory
-s shell
-c comment
-k template
-f inactive
-e expire mm/dd/yy
-p passwd
Then there are a few arguments with no explanation:
-o, -m, -n, and -r
So say that you wanna add a user named "user" with password "resu"
belonging to the group root with / as home directory using /bin/tcsh
as shell, that would look as this:
adduser -p resu -g root -d / -s /bin/tcsh user
------------------------------------------------------------------------------
alias
The alias command set's an alias, as this: alias du='du -h'
This means that whenever you type: du
it will really do: du -h
Typing alias by it self will display all set aliases.
For more information on the alias command do: help alias
------------------------------------------------------------------------------
apropos
apropos checks for strings in the whatis database. say that you
are looking for a manual page about the `shutdown` command.
Then you can do: apropos shutdown
for more information, do: man whatis
Or: man apropos
------------------------------------------------------------------------------
awk
awk is a text formatting tool, that is HUGE, it's actually a whole
language, some say it's not totally wrong to say that awk is not
far off from a scripting version of C.
However I wouldent go as far as to say that there resemblance
is that great.
awk's most common use is about the same as 'cut', and it works like
this: awk [argument-1] [argument-2] ....
Here's some example's of converting an URL:
echo "http://www.bogus.com/one/two.htm" | awk -F'/' '{print $3}'
This will return: www.bogus.com
The -F will set a delimiter, and the '{print $3}' will print the
third feild, separated by the delimiter, which is www.bogus.com,
because there is 2 slashes, which makes the second slash the second
feild, and so www.bogus.com is the third feild.
Here's another example:
echo "http://www.bogus.com/one/two.htm" | awk -F'/' '{print $(NF)}'
This will return: two.htm
The -F set's the delimiter, which once again is /, but this time
we have used $NF which always resembles the last feild.
Another example with NF is this:
echo "http://www.bogus.com/one/two.htm" | awk -F'/' '{print $(NF - 1)}'
This will return: one
Because $(NF - 1) means the last feild minus one feild, which always
will be the next last feild.
You only have to use the ()'s around variables when you do something
with them like here "$(NF - 1)", but you can use $(var) all the time
if you want.
Here's another example:
echo "http://www.bogus.com/one/two.htm" | awk -F'/' '{print $3 "/" $(NF - 1)}'
This will return: www.bogus.com/one
It will first print out the third feild separated by /'s, which is
www.bogus.com, then it will print a /, and then it will print out
the next last feild which is one.
Here is a very shoer final example of awk:
echo "http://www.bogus.com/one/two.htm" | awk '{ while ( $(1) ) print }'
This will return: "http://www.bogus.com/one/two.htm" forever.
The "while ( $(1) )" means that as long as there is first feild,
it will print the line line.
And since there will always be a first feild it will continue
forever.
while in awk works as this: while ( condition ) action
As I said, awk is huge and is actually a whole language, so
to explain all of it it would need a tutorial of it's own.
So I will not go any deeper into awk here, but you can as always
read it's manual page which is quite large.
So, for more info do: man awk
------------------------------------------------------------------------------
basename
basename will strip directory and suffix from filenames.
This command only have the two following flags:
--help display this help and exit
--version output version information and exit
It works like this:
alien:~$ basename /usr/local/bin/BitchX -a
BitchX
alien:~$ basename http://www.domain.com/path/to/file.html
file.html
alien:~$
For more info do: man basename
------------------------------------------------------------------------------
bc
A precision calculator, can be used with the following arguments:
-l Define the standard math library.
-w Give warnings for extensions to POSIX bc.
-s Process exactly the POSIX bc language.
-q Do not print the normal GNU bc welcome.
-v Print the version number and copyright and quit.
-------------------------------------------------------------------------------
BitchX
BitchX is usually not default on any system, but it's the far
msot advanced IRC client to *nix.
BitchX started as a script to ircii (ircii is irc2 an extended
irc protocol, also EPIC which is more bareboned then BitchX is
made from ircii), until BitchX got hard coded to the protocol
in C, by panasync I belive.
BitchX has alot of arguments but can be executed without any
arguments.
This is the synatx: BitchX [arguments] <nickname> <server list>
And here are the arguments anyway:
-H <hostname> this is if you have a virtual host.
-c <#channel> auto join a channel, use a \ infront of the #
-b load .bitchxrc or .ircrc after connecting to a server
-p <port> connect on port (default is 6667)
-f your terminal uses flow controls (^S/^Q),
so BitchX shouldn't
-F your terminal doesn't use flow control (default)
-d dumb terminal mode (no ncurses)
-q dont load the rc file ~/.ircrc
-r <file> loads file as list of servers to connect to
-n <nickname> set the nickname to use
-a adds default servers and command line servers
to server list
-x runs BitchX in "debug" mode
-Z use NAT address when doing dcc
-P toggle check pid.nickname for running program
-v show client version
-B fork BitchX and return you to shell. pid check on.
-l <file> loads <file> in place of your ~/.ircrc
-L <file> loads <file> in place of your .ircrc and
expands $ expandos
The most common way of starting BitchX is this, say that you want
to have the nick 'Bash' on server irc.bogus.com, then you can do:
BitchX Bash irc.bogus.com
There is so much to say about BitchX that it would need a tutorial
of it's own, I'm currently writing a BitchX script, so maybe
I'll write a BitchX tutorial some time =)
-------------------------------------------------------------------------------
bzcat
bzcat will uncompress a .bz2 file 'on the fly' as it cat's it.
the actual file will remain compressed after bzcat has displayed
the contents.
bzcat has to my knowlidge only one switch, and that's
-s, that uses less memory.
bzcat works like this:
bzcat file.bz2
This can be good if you wanna search something in a text file
that has been bzip2'd.
Examples:
bzcat file.bz2 | grep 'text string'
bzcat file.bz2 | wc -l
-------------------------------------------------------------------------------
bzip2
Compression tool, compresses harder then the standard gzip.
bzip2 can be used with the following arguments:
-h --help print this message
-d --decompress force decompression
-z --compress force compression
-k --keep keep (don't delete) input files
-f --force overwrite existing output files
-t --test test compressed file integrity
-c --stdout output to standard out
-q --quiet suppress noncritical error messages
-v --verbose be verbose (a 2nd -v gives more)
-L --license display software version & license
-V --version display software version & license
-s --small use less memory (at most 2500k)
-1 .. -9 set block size to 100k .. 900k
Normally used as: bzip2 -d file.bz2 (to decompress a file)
or bzip2 -z file (to compress a file)
-------------------------------------------------------------------------------
cat
cat followed by a filename will bring the contents of the file
out to the screen (stdout), and can be used with the following
arguments:
-A, --show-all equivalent to -vET
-b, --number-nonblank number nonblank output lines
-e equivalent to -vE
-E, --show-ends display $ at end of each line
-n, --number number all output lines
-s, --squeeze-blank never more than one single blank line
-t equivalent to -vT
-T, --show-tabs display TAB characters as ^I
-u (ignored)
-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
--help display this help and exit
--version output version information and exit
-------------------------------------------------------------------------------
cc
C compiler, can be used with ALOT of arguments, do a man cc to find
out just how many, it's normally used to compile a .c source file to an
executable binary, like this:
cc -o program program.c
-------------------------------------------------------------------------------
cd
change directory, works as this:
cd /way/to/directory/I_want_to/be/in/
No further explanation needed.
-------------------------------------------------------------------------------
chattr
This is a very powerful command with which you can change the
attributes on an ext2 file system.
This means that you can make a file impossible to remove
for as long as the attributes are there.
The attributes that can be added or removed are the follwoing:
A Don't update atime.
S Synchronous updates.
a Append only.
c Compressed.
i Immutable.
d No dump.
s Secure deletion.
u Undeletable.
So here is an example:
chattr +iu /etc/passwd
This makes it impossible to remove the /etc/passwd file unless
you first do:
chattr -iu /etc/passwd
This can also be good for the logs, esecially, with the a attribute.
To see the attributes, use: lsattr
For more info do: man chattr
-------------------------------------------------------------------------------
chmod
chmod is a very useful command, it changes the rights of any file.
To understand this command you need to understand how the permission
line works:
-rwxr-xr-x 1 alien users 58 Feb 7 13:19 file1
-rw-r--r-- 1 alien users 3.1k Feb 3 15:47 file2
Let's break the -rwxr-xr-x down into 4 sections:
- rwx r-x r-x
The first - you can not change, that tells what sort of file it is,
as if it's a special file, a directory or a normal file.
The second rwx is the rights of the owner of the file.
The third r-x is the rights the group of the file has.
And the fourth r-x tells us what right others/anyone else has.
The rights can be:
r read rights.
w write rights.
x execute rights.
s suid (su id, execute with someome else's uid, usually root)
t saves the programs text on the swap device
X executes file only if it's in a dir that has execute rights
Then we need to know in what of those 3 last fields to set those
rights, they can be set to:
a all (changes the 3 fields syncroniously)
u user
g group
o others/anyone else
You can add or remove rights with the following arguments:
+ add a right
- remove a right
= absolute right
So say now that we have a file called file1, that looks like this:
-rwxr-xr-x 1 alien users 58 Feb 7 13:19 file1
And we wanna take away all execution rights.
Then we can either do:
chmod a-x file1
or
chmod ugo-x file1
And if we wanna make a file executable to everyone in it's group,
in this case the group "users", then we do:
chmod g+x file1
The other way to do this, is to use octal numbers to set the
rights in the permission line.
This requires a bit more thinking if your not use to it, but here's
how it works:
First we break up the permission line into 3 sections again (not
counting the leading - or d), and then we put numbers on each
of the 3 fields in each of the 3 sections.
- rwx rwx rwx
421 421 421
Now to change a line to say: -rwxrx-r-x
You would:
x and r in the last field, that would mean 1+4=5, then the same thing
in the middle field, and last we have r, w and x in the first so then
we count them all, 1+2+4=7.
If we now line up our results of this little mathematic we get: 755
And so to change a permission line to -rwxrx-r-x we do:
chmod 755 <file>
Here's how it looks:
Oct Bin Rights
0 0 ---
1 1 --x
2 10 -w-
3 11 -wx
4 100 r--
5 101 r-x
6 110 rw-
7 111 rwx
Then we have the suid stuff for this with octal counting, that you set
before the normal rights, I'll explain that in a bit, first here
is the number codes for the special options as suid.
7*** SUID (user & group and set's file +t)
6*** SUID (user & group)
5*** SUID +t (saves the files text to the swap partition and SUID user)
4*** SUID (user)
3*** SUID (group and set's file +t)
2*** SUID (group)
1*** +t (saves the files text to the swap partition)
0*** nothing
Here's how it looks:
Oct Bin Rights
- --- rwx rwx rwx
0 0 --- --- ---
1 1 --- --- --t
2 10 --- --s ---
3 11 --- --s --t
4 100 --s --- ---
5 101 --s --- --t
6 110 --s --s ---
7 111 --s --s --t
So if you have a file that we can call 'foo.sh' and you wanna make
so that only the user has write permissions to it, the user
and group has read and execute permissions, and all others has no
rights at all to it.
Then we would count: others, 0, group 5, user 7, and then to SUID
the group we add a 2 in front of what we have, which means:
chmod 2750 foo.sh
This will make foo.sh's permission line look like this:
-rwxr-s---
To do the exact same with characters, you do:
chmod u+rwx,go-rwx,g+s foo.sh
The most common premissions for files is
Executeble: (755) -rwxr-xr-x
Non-Executeble: (644) -rw-r--r--
The easyest way of setting these is by eather do:
chmod 755 file
or
chmod =rwxrxrx file
chmod 644 file
or
chmod =rwrr file
For more information, do: man chmod
-------------------------------------------------------------------------------
chown
chown changes owner of a file, it can actually also change the group.
it works like this:
chown user file
This would change the owner of the file to user, but note that
you can not change to owner of a file to a user that's owned
by someone else, same thing is that you can not change another
users files so that you own them.
Basicly, you need to be root to for this command in most cases.
If you wanna change both the user and the group of a file, you do
like this:
chown user.group file
That would change the owner of the file to user and the group
of the file to group.
For more info on this do: man chown
-------------------------------------------------------------------------------
chroot
runs a command or interactive shell with special root directory.
It works like this:
chroot /new/root/directory/ command
This can be good for some programs or commands, that rather
would have / as root directory then ~/ etc.
-------------------------------------------------------------------------------
cmp
compares 2 files for differences, it can be used with the
following arguments:
-l Print the byte number (decimal) and the differing byte
values (oc- tal) for each difference.
-s Print nothing for differing files; return exit status only.
It works like this:
cmp file1 file2
Or
cmp -s file1 file2
Not a very big, but still useful command.
-------------------------------------------------------------------------------
cp
copy, copy's a file from one location to another, may also copy
one filename to another, used as this:
cp file /some/other/dir/
or
cp file file.old
-------------------------------------------------------------------------------
crontab
Crontab has already been explained in this tutorial.
-------------------------------------------------------------------------------
cut
cut is a very powerful command, that allows you to cut in texts,
It works like this: cut [arguments] <file>
-b, --bytes=LIST
output only these bytes
-c, --characters=LIST
output only these characters
-d, --delimiter=DELIM
use DELIM instead of TAB for field delimiter
-f, --fields=LIST
output only these fields
-n
(ignored)
-s, --only-delimited
do not print lines not containing delimiters
--output-delimiter=STRING
use STRING as the output delimiter
the default is to use the input delimiter
--help
display the help and exit
--version
output version information and exit
One of the many ways to use it is like this, say that you have a file
named "hostlist" that contains this:
beta.linux.com has address 216.200.201.197
shiftq.linux.com has address 216.200.201.195
irc.linux.com has address 216.200.201.199
oreilly.linux.com has address 208.201.239.30
srom.linux.com has address 204.94.189.33
admin.linux.com has address 216.200.201.194
And you ONLY wanna list the IP's from it, then you do this:
cut -d ' ' -f 4 testfile
That will output only the IP's, first we set the delimiter to ' '
which means a space, then we display the 4'th field separated by
the delimiter, which here is the IP's.
Or that you have a file (say named column.txt) that contains this:
something if we have to
or someone cut and paste
likes to write the columns.
in columns, we So what do
don't like that we do about
especially not this ?
To cut out each column is done like this:
cut -c 1-14 column.txt
cut -c 23-40 column.txt
This would fist cut the file lengthwise and display characters
1-14 and then the same thing again but characters 23-40.
Now a simple way to get them in a long row instead of columns
in a file is this:
cut -c 1-14 column.txt > no-columns.txt
cut -c 23-40 column.txt >> no-columns.txt
-------------------------------------------------------------------------------
date
date alone returns the current date and time in the following format:
day month date hr:min:sec timezone year
But can be executed with the following arguments:
%% a literal %
%a locale's abbreviated weekday name (Sun..Sat)
%A locale's full weekday name, variable length (Sunday..Saturday)
%b locale's abbreviated month name (Jan..Dec)
%B locale's full month name, variable length (January..December)
%c locale's date and time (Sat Nov 04 12:02:33 EST 1989)
%d day of month (01..31)
%D date (mm/dd/yy)
%e day of month, blank padded ( 1..31)
%h same as %b
%H hour (00..23)
%I hour (01..12)
%j day of year (001..366)
%k hour ( 0..23)
%l hour ( 1..12)
%m month (01..12)
%M minute (00..59)
%n a newline
%p locale's AM or PM
%r time, 12-hour (hh:mm:ss [AP]M)
%s seconds since 00:00:00, Jan 1, 1970 (a GNU extension)
%S second (00..60)
%t a horizontal tab
%T time, 24-hour (hh:mm:ss)
%U week number of year with Sunday as first day of week (00..53)
%V week number of year with Monday as first day of week (01..52)
%w day of week (0..6); 0 represents Sunday
%W week number of year with Monday as first day of week (00..53)
%x locale's date representation (mm/dd/yy)
%X locale's time representation (%H:%M:%S)
%y last two digits of year (00..99)
%Y year (1970...)
%z RFC-822 style numeric timezone (-0500) (a nonstandard extension)
%Z time zone (e.g., EDT), or nothing if no time zone is determinable
For example, if you want to the time as hr:min:sec day, you would do:
date +'%H:%M:%S %a'
Or if you wanted to display the name of the month only, you would do:
date +%B
-------------------------------------------------------------------------------
dc
dc is an arbitrary precision calculator.
man dc for more info.
-------------------------------------------------------------------------------
dd
disk duplicator, this is a very powerful command, that is
useful for doing backups as well as creating boot floppy's
from images.
Say now that you have a Slackware standard boot floppy image (bare.i)
and you want to write it to a floppy, then you do this:
dd if=bare.i of=/dev/fd0 conv=sync
If you instead have a RedHat or Mandrake boot image, just replace
the bare.i in the line with boot.img, under the condition that
you are standing in a directory that contains that specific image.
The conv=sync part is just there to make sure that the disks are
synced.
dd is a quite big command so I suggest you take a look at the man page.
-------------------------------------------------------------------------------
declare
declare will declare a variable and may set attributes to it.
The attributes declare can set or use with the following flags are:
-p show variable with attributes.
-a to make a variable(s) an array (if supported)
-f to select from among function names only
-F to display function names without definitions
-r to make variable(s) readonly
-x to export variable(s)
-i to make variable(s) have the `integer' attribute set
Using `+' instead of `-' turns off the given attribute(s) instead
of setting them.
If declare is used within a function, the variables will be
local, the same way as if the `local` command had been used.
The -r option works the same as the `readonly` command.
And the -r option can not be removed once it's set.
Here's a short example:
declare -xr foo=bar
This would do the same as to do:
export foo=bar; readonly foo
For more info on this, do: help declare
-------------------------------------------------------------------------------
depmod
depmod loads kernel modules, and is a very powerful command,
it's greatest use is that it can reload all kernel modules
in a single line:
depmod -a
This is especially good if you have recompiled some modules and
installed them, and you don't wanna reboot the system.
The command also allows you to load single modules or several
modules, like this:
depmod module1.o module2.o ... etc.
For more info, man depmod
-------------------------------------------------------------------------------
df
Reports filesystem disk space usage.
df can be used with the following arguments:
-a, --all
include filesystems having 0 blocks
--block-size=SIZE use SIZE-byte blocks
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-H, --si
likewise, but use powers of 1000 not 1024
-i, --inodes
list inode information instead of block usage
-k, --kilobytes
like --block-size=1024
-l, --local
limit listing to local filesystems
-m, --megabytes
like --block-size=1048576
--no-sync
do not invoke sync before getting usage info (default)
-P, --portability
use the POSIX output format
--sync invoke sync before getting usage info
-t, --type=TYPE
limit listing to filesystems of type TYPE
-T, --print-type
print filesystem type
-x, --exclude-type=TYPE
limit listing to filesystems not of type TYPE
-v (ignored)
--help display this help and exit
--version
output version information and exit
My favorite is to use: df -h
-------------------------------------------------------------------------------
dhcpcd
dhcpcd is used to obtain an IP if you have dynamic IP on a LAN
such as a cable modem with dynamic IP.
-------------------------------------------------------------------------------
dialog
The dialog command has already been explained in this tutorial.
-------------------------------------------------------------------------------
diff
diff is a very large command that finds the difference between
two files, it's very handy to have to make patches.
The basic use of diff is as follows:
diff file1 file2
for more and full info on this command, do: man diff
-------------------------------------------------------------------------------
dir
Same as "ls".
-------------------------------------------------------------------------------
dmesg
dmesg can print or control the kernel ring buffer.
by default it'll show a log of loaded and unloaded modules
and other kernel events, like initialization if RAM disks etc.
(this is flushed at each reboot)
This is useful to make a boot.messages file, bu simply doing this:
dmesg > boot.messages
If there is any errors at the boot up this command is the first
you would use to try to determen the error.
This is the syntax of dmesg (cut'n'paste of the man page):
dmesg [ -c ] [ -n level ] [ -s bufsize ]
The options (-c/-n/-s) means the following:
-c
clear the ring buffer contents after printing.
-s bufsize
use a buffer of bufsize to query the kernel ring
buffer. This is 8196 by default (this matches the
default kernel syslog buffer size in 2.0.33 and
2.1.103). If you have set the kernel buffer to
larger than the default then this option can be
used to view the entire buffer.
-n level
set the level at which logging of messages is done
to the console. For example, -n 1 prevents all
messages, expect panic messages, from appearing on
the console. All levels of messages are still
written to /proc/kmsg, so syslogd(8) can still be
used to control exactly where kernel messages
appear. When the -n option is used, dmesg will not
print or clear the kernel ring buffer.
When both options are used, only the last option on
the command line will have an effect.
When you use the kill you can either use the numeric code, as
say that we have a PID 1234 that we wanna kill, then we can either
do: kill -9 1234 or we can do: kill -KILL 1234
So you don't have to include that leading SIG in the signals
when you use them by name.
-------------------------------------------------------------------------------
killall
killall is the same as kill but kills processes by name,
As say that you have 10 processes running all named: httpd
and you wanna kill them all in one command.
Then: killall -9 httpd would be the way to go about it.
-------------------------------------------------------------------------------
lastlog
lastlog is a command that shows you a list of the users and when
they last logged in, from what host and on which port.
lastlog can be used with the following arguments:
-u username
-t number of days
so if I wanna check if a user named 'user' has logged in during
the last 50 days I do: lastlog -u user -t 50
-------------------------------------------------------------------------------
ldconfig
ldconfig updates the list of directory's in where library's can be
found as /lib and /usr/lib, if you wanna add a directory to this you
can add them in /etc/ld.so.conf
By just typing `ldconfig` you will update this, but it can
also be executed with more arguments, for more info on this
command do: man ldconfig
Just note that this is not really a command that you will use
every day.
-------------------------------------------------------------------------------
ldd
ldd can check what librarys a dynamicly executable file needs.
and it can have the following switches:
--help print this help and exit
--version print version information and exit
-d, --data-relocs process data relocations
-r, --function-relocs process data and function relocations
-v, --verbose print all information
It works like this:
ldd <file>
Example:
ldd /sbin/ifconfig
-------------------------------------------------------------------------------
less
less is more then more ..... ummmm
less works a bit like cat but it will stop at each screen and you
can scroll up and down in the file to view it's contents,
it works basicly like this: less <textfile>
Do a: less --help
For a full index of it's commands, and note that you get out
of less by pressing the letter 'q'.
-------------------------------------------------------------------------------
lilo
lilo is the LInux LOader, and is on most distros the default
boot loader, with lilo you can rewrite your boot sector and
everything that involves your booting or switching between
several installed operating systems, lilo's configuration file
is /etc/lilo.conf
for more info about lilo and what lilo can do do: man lilo
-------------------------------------------------------------------------------
ln
link, with ln you can link any file, this is essential to *nix
as, say that you have a config file that needs to be in the same
dir as it's program but you want it in /etc with all the other
configuration files, then you can link it to /etc so the link
appears in /etc and works just like the real file.
Usually ln is used to set symbolic links (sym links) where you
can see the difference of the link and the file and you can remove
the link without it affecting the real file.
A symbolic link is set in this way: ln -s file link
-------------------------------------------------------------------------------
lndir
link directory, about the same as ln but links directory's,
see the: man lndir
-------------------------------------------------------------------------------
loadkeys
loadkeys, basicly works like: loadkeys /usr/lib/kbd/keymaps/<keymap>
but also has some arguments (that I never used), if you want
more info: man loadkeys
-------------------------------------------------------------------------------
locate
locate can locate any file that's read into a database,
you update this database if you as root type: updatedb
locate works basicly like: locate <whatever-you-wanna-find>
but can be executed with alot of arguments, do: locate --help
or for more info: man locate
-------------------------------------------------------------------------------
logout
logout does what it says, it logs you off the shell.
-------------------------------------------------------------------------------
lpq
line printer que, checks if you have any printer jobs on que.
-------------------------------------------------------------------------------
lpr
line printer, has alot of commands, but basicly works as: lpr <file>
to print a file, the lpr command has alot of arguments,
do: man lpr for more info.
-------------------------------------------------------------------------------
lprm
line printer remove, removes any qued jobs (lpq) by there entry number.
-------------------------------------------------------------------------------
ls
this is the most basic of all basic commands to know.
ls lists the contents of a directory, if you type just `ls`
it will list the contents of the current directory, but it can also
be used as `ls /way/to/some/other/dir/` to list the contents of
some other directory, ls has alot of arguments which are:
-a, --all
do not hide entries starting with .
-A, --almost-all
do not list implied . and ..
-b, --escape
print octal escapes for nongraphic characters
--block-size=SIZE
use SIZE-byte blocks
-B, --ignore-backups
do not list implied entries ending with ~
-c
sort by change time; with -l: show ctime
-C
list entries by columns
--color[=WHEN]
control whether color is used to distinguish file
types. WHEN may be `never', `always', or `auto'
-d, --directory
list directory entries instead of contents
-D, --dired
generate output designed for Emacs' dired mode
-f
do not sort, enable -aU, disable -lst
-F, --classify
append indicator (one of */=@|) to entries
--format=WORD
across -x, commas -m, horizontal -x, long -l,
single-column -1, verbose -l, vertical -C
--full-time
list both full date and full time
-g
(ignored)
-G, --no-group
inhibit display of group information
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-H, --si
likewise, but use powers of 1000 not 1024
--indicator-style=WORD
append indicator with style WORD to entry names:
none (default), classify (-F), file-type (-p)
-i, --inode
print index number of each file
-I, --ignore=PATTERN
do not list implied entries matching shell PATTERN
-k, --kilobytes
like --block-size=1024
-l
use a long listing format
-L, --dereference
list entries pointed to by symbolic links
-m
fill width with a comma separated list of entries
-n, --numeric-uid-gid
list numeric UIDs and GIDs instead of names
-N, --literal
print raw entry names (don't treat e.g. control
characters specially)
-o
use long listing format without group info
-p, --file-type
append indicator (one of /=@|) to entries
-q, --hide-control-chars
print ? instead of non graphic characters
--show-control-chars
show non graphic characters as-is (default)
-Q, --quote-name
enclose entry names in double quotes
--quoting-style=WORD
use quoting style WORD for entry names:
literal, shell, shell-always, c, escape
-r, --reverse
reverse order while sorting
-R, --recursive
list subdirectories recursively
-s, --size
print size of each file, in blocks
-S
sort by file size
--sort=WORD
extension -X, none -U, size -S, time -t, version -v
status -c, time -t, atime -u, access -u, use -u
--time=WORD
show time as WORD instead of modification time:
atime, access, use, ctime or status; use
specified time as sort key if --sort=time
-t
sort by modification time
-T, --tabsize=COLS
assume tab stops at each COLS instead of 8
-u
sort by last access time; with -l: show atime
-U
do not sort; list entries in directory order
-v
sort by version
-w, --width=COLS
assume screen width instead of current value
-x
list entries by lines instead of by columns
-X
sort alphabetically by entry extension
-1
list one file per line
--help display this help and exit
--version output version information and exit
Some good examples are:
ls -la
ls -laF
ls -laF --color
ls -d */
Also see earlier in this tutorial about the `alias` command
-------------------------------------------------------------------------------
lsattr
list attributes, this command lists a files file system attributes.
For more info see: man lsattr
-------------------------------------------------------------------------------
lsmod
list modules, lists all loaded modules with a very brief information.
-------------------------------------------------------------------------------
lsof
list open files, this is a huge command, so if you really
wanna find out more about this interesting command you will have
to read the manual page for it.
But here's an example of use for it:
lsof -p 1
Which would be the same as:
lsof -p `pidof init`
Here's another example:
lsof -p `pidof httpd | sed 's/\ /,/g'`
The "-p" means that the following argument will be a PID (Process ID).
The "sed" part in the later example replaces any spaces with "," since
lsof doesnt want spaces between the pids, as the output of pidof gives.
For more info see: man lsof
-------------------------------------------------------------------------------
lynx
lynx is a console based world wide web browser, that has alot of
arguments with which it can be executed, but it basicly works like
this: lynx <url>
If you press 'g' while in lynx you can type in the url where you
wanna go, and if you press 'q' you quit lynx.
You search in text with lynx with '/' and move around with
the arrow keys and the TAB key.
A tips is that lynx works as a file manager, as this: lynx </path/>
A good usage for lynx is that you can use it as direct downloader,
like this: lynx -souce ftp://ftp.bogus.com/foo/bar.tar.gz > bar.tar.gz
For more help or information do: lynx --help
Or: man lynx
-------------------------------------------------------------------------------
mail
mail is most commonly used to just check your mail in the most
simple way by just typing `mail`, but it can also be used
with alot of arguments, I have personally never used
any arguments to the mail command, but if you wanna check
them out do: man mail
-------------------------------------------------------------------------------
man
manual pages, there are several different manual pages, say for example
the command exec, `man exec` should bring you little, while
`man 3 exec` should bring you the C function manual on exec.
The man pages traditional way of storing is:
man1 misc user commands
man2 C programming functions
man3 more C programming functions
man4 network related manuals
man5 system related files
man6 game manuals
man7 misc technical manuals
man8 misc superuser commands
man9 misc system/devices
I may be wrong about the category's there, but that's how it seems
to me.
Anyway, to bring up a manual page simply do: man <command>
or: man <number> <command>
-------------------------------------------------------------------------------
mc
midnight commander is a visual shell for *nix Operating Systems.
mc is quite large and has alot of arguments, I personally don't use
midnight commander at all, but if you wanna learn more about it
do: man mc
-------------------------------------------------------------------------------
mesg
mesg is a command with which you control if other users should
have write access to your terminal, as `wall` messages, `write`
or anything similar.
mesg y turns on the access for others to write to your terminal.
mesg n turns off the access for others to write to your terminal.
-------------------------------------------------------------------------------
mkdir
make directory, creates a directory, works as: mkdir [arguments] dir/
The arguments can be as follows:
-m, --mode=MODE see chmod's octal (numerical) modes
-p, --parents no error if existing, make parent
directories as needed
--verbose print a message for each created directory
--help display the help and exit
--version output version information and exit
mkdir is most commonly used as: mkdir <newdir>
-------------------------------------------------------------------------------
mknod
mknod is used to create special files, as devices.
mknod's syntax is this: mknod [arguments] <name> <type> [MAJOR MINOR]
It can be used with the following arguments:
-m, --mode=MODE
set permission mode (as in chmod), not 0666 - umask
--help
display this help and exit
--version
output version information and exit
MAJOR MINOR are forbidden for <type> p, else they must be used.
b create a block (buffered) special file
c, u create a character (unbuffered) special file
p create a FIFO
You need to know the devices major/minior number if you gonna use this
command, those are located in /usr/src/linux/Documentation/devices.txt
that comes with the kenrnel source.
The "char" is the minior and the number before the devices are the
major numbers so say that you wanna make a new /dev/null for some
reason, then you read the devices.txt and see this:
You can use OCT the same way .. with as many leading 0's as you please
0173.0173.0173.0173 or 000173.00000173.000173.000000000000000000000173,
it still means IP 123.123.123.123
And ofcorse to add on the confusion you can mix the methods.
0173.0x7b.00173.123
Now there is even more to this like that you can add any multiple of the
number 4294967296 (2^32) to the number without the IP changing ....
But let's not get into that ....
So basically typing:
http://0173.0x7b.00173.123/
in your web browser will end you up at IP 123.123.123.132 (which doesnt excist)
but the idea is the same for everything, so if you see some lame spammer
thinking that you wont know from what address he sent something ...
The just back count it and send abuse mail to his internet service provider.
-------------------------------------------------------------------------------
If someone has more questions mail, them to me at: alien@ktv.koping.se
maybe I'll include them in the tutorial, but I'll do my best to answer
the questions anyway.
===============================================================================
10 - Basics of the common UNIX and Linux text editors.
===============================================================================
Here we go with the text editors vi, ed and emacs.
ed is just explained for historical reasons.
-------------------------------------------------------------------------------
Most commonly used VI commands
-------------------------------------------------------------------------------
Here we go with the vi commands, these are unlogical but still good to know
because all computers doesn't have emacs, joe, pico and so on.
Solaris / SunOS comes default with vi as only text editor.
Vi has 2 basic modes, command mode and edit mode, you change between them
by pressing the Esc button, and to start to edit a file you must have a
free line, which you get by pressing, Esc followed by `o`.
vi is bound to be the hardest and most confusing text editor to learn,
and it has LOTS of commands, I included just a few of the most used
commands.
So here we go with the vi commands:
Inserting text
esc + i insert text informant of the cursor
esc + a append text after the existing text
esc + O opens new line above the current line
esc + o opens new line under current line (insert mode)
Deleting text
esc + x deletes one character
esc + 5x deletes five charters
esc + dw deletes a word
esc + 5dw deletes five words
esc + dd deletes the whole line
esc + D deletes the line from cursor and forward
esc + d) deletes the sentence from cursor and forward
esc + d( deletes the sentence from cursor and backwards
esc + u undelete
Note: esc + d) or d( removes the sentence from cursor and forward/backwards
until it reaches a dot "."
Moving around in VI:
Make sure you are in command mode and the following letters will do:
j moves you down
k moves you up
h moves you left
l moves you right
Finding Text
Hit esc then type in a / you then go to the bottom of the screen
where you will see your / type in the text to look for.
ie. /Linux
that will find the word `Linux` in the open file.
Replacing Text
Hit esc and do: :start,stop,s/s_text/r_text/g
: indicates that this is an ex command
start is the starting line number
stop is the stopping point
s is the substitute command
s_text is the search string (the text you are looking for )
r_text is the text you are replacing with
g is global
Example:
Esc + :5,8,s/l/ll/g
This would replace all "l"'s with "ll" on lines 5 to 8.
Note to Replacing Text:
Line numbers can also be:
. current line
$ last line
All you really need to know to start using emacs is how to save and quit.
( ^X ^S ^X ^C will save and quit, a tip is: hold down ^ (Ctrl) and
press X S X C )
===============================================================================
-------------------------------------------------------------------------------
===============================================================================
This should be enough for you to start to script in bash, and make useful
scripts.
The only thing that limits what you can do is your imagination (well almost).
Go over this tutorial several times so you really understand everything.
If you accomplish that, you have a really good chance of learning UNIX well.
And that's what it's all about, to learn new things and explore new ways.
As long as you learn you live, not the contrary.
This tutorial turned out rather large, but I hope that those of you out there
that have the determination to learn shell scripting, also have the patinace
to read it all, and if not, you can always use it as a small dictionary.
I've got the question many times, which Linux distribution is the best ....
The question in it self is pointless and as ilitterat as asking
what version linux is up to....
The later question can only be answerd with a kernel version number,
and that is what Linux is, Linux is the kenrel and all distributions
use the same kernel, everything else in the system is just "stuff around
the kernel", to this point I've found that Mandrake is the distibution
that is most compleat for my needs, and it's suitable for beginners
aswell as for proffessionals, and it has nice configuration tools
that have been written especially for Mandrake.
But as I said, a Linux is a Linux, and the main difference between different
distributions is the package manager, where of rpm is the most stanard
and accepted, though I find Debians dpkg good aswell.
This is to the difference of distributions that have no indiginous package
manager like Slackware, that emulates a package manager with it's .tgz
package format (note that .tar.gz is not .tgz since .tgz should have it's
packages compressed with there path beginning from / )
Now there is nothing wrong with that if you like to compile most stuff on the
system your self, and many people preffer to do that.
My conclution is that the best distrinution is the one you personally
like the best, the one that fits _your_ needs.
So anyway, when you know bash scripting well enough, my suggestion is to
learn C programming, which, if you look at it with bash behind you,
isn't that hard.
So, I better go to bed and stop this nonses now.
Happy scripting all of you out there.
===============================================================================
--------------- Written by Billy Wideling <-> alien@koping.net ----------------
===============================================================================