A SIMPLE SHELL/TELNET TUTORIAL By: Cerberus ares@armory.com http://www.geocities.com/ares_102/ BASH, or the Bourne Again SHell, is the most popular shell used by Linux and UNIX today. It is a modification of the origional System V UNIX ash shell. Also, it is one of the more compatible shells. It is for this reason that I will be using this particular shell. However, most of these commands/syntax will work with most other shells, if not all. Only when we get into scripting will the BASH shell stand out in its uniqueness. This tutorial is mainly aimed at Windows users who would like to get a chance to use a *NIX shell without actually installing a *NIX OS, however the information (excluding the first part) is universal, it doesn't matter if you're using SSH, telnet, or the actual console. Lets get started. Part I: Telnet In Windows, go to START->RUN and type: telnet and press enter. This is the Windows version of telnet, a useful tool in all aspects. The telnet application allows a connection to another computer, for teh purpose of using that computer as if it were your own. Basically, consider telnet a tool that allows you to get commands on the remote computer sent to you (the output). That is what it is intended for, and all you can use it for in WIndows. Now, in Linux, UNIX, etc (referred to as *NIX), we can telnet to any port we decide to, we are not limited at all by only being able to telnet to telnet ports. This is one main reason why *NIX is good for hacking and security audits. *NIX allows telnet to connect to non-telnet ports. However, we will be using telnet for its intended purpose today (aaaawwww), we will be telnetting to a telnet port (23), and connecting to that machine. To do this, we need what is called a SHELL account. Shell accounts are not usually free, but occasionally you can get a free one. Your ISP might offer one, check with them. If all else fails, these are some good Shell accounts that are FREE: cjb.cyberspace.net freeshells.com deepthought.armory.com I suggest you at least donating to whichever one you choose, its the right thing to do. Now then, connect to the remote computer by entering in the address. You will usually login as guest, request, etc. to request a free account. Once you ahve your account set up, go back in a few days or so (some are faster), and again telnet to that remote server, only this time using your login/pwd. Okay, now you're connected. this ends the telnet tutorial, now with the BASH tutorial: Part II: THE SHELL Okay, so you have this $ thing. What is this? First of all, the dollar sign you see is a prompt, the remote server is waiting for you do do something. Type the following, and press ENTER: echo "hello." Nice, you now can print stuff, kinda useless, eh? not hardly. The beauty of *NIX is that it combines many small programs that just do one thing, so that you can combine them to preform a complex task. Now, lets start with taking a look at what's in our home directory (the path default): ls -l the -l specifices to print a long list, showing file permissions, the name, the date, the size, etc. This is similar to the dir command in DOS, but it is more powerful. Okay, now lets edit the following file, either using vi or joe: vi .bash_profile OR joe .bash_profile This opens the file that is run every time you log in. scroll to the bottom and type : echo "Welcome to my account." and press for vi: ESCAPE : write : quit for joe: Control K + X and we've exited. COngradulations! You've just edited your first *NIX configuration file, a common, and thus needed skill. YOu may wish to re-login, or you can simply type the following: sh .bash_profile the sh command invokes a shell, which reads the file specified as if it were a script (which it is). We will delve into this later. For now, lets make a listing of our directory, then save it to a file, so we can look at it later: ls -l > ls_1.txt What this does is it redirects the output of the command 'ls -l' to a file, which is ls_1.txt. The > redirector does this. Now, lets take a look at that file. We just want to see what's in the file, not edit it, so we'll type: cat ls_1.txt If the output is too long, we can use another redirector, the PIPE. This is located usually on teh same key as teh backspace key. It is a little verticle line. Lets make it to where the output of the 'cat' will go to another program, which is 'more': cat ls_1.txt | more this makes it to where you can page through it...nice. Now, then, we shall cover another simple command, the who, or w command (either will work): w Will output a list of all logged in users, their task(s), when they logged in, etc. Nice. Lets suppose though that we wanted to use a single command to output the task(s) of our friend, john: w | grep "john" as you will remember, teh | operator redirects the output of 'w' to 'grep "john"', grep is a tool that searches for text in a file, or whatever input is. For instance, if you wanted to write a file of current users and their tasks, and then search that for john: w > users.txt cat users.txt | grep "john" as you will recall from earlier, cat displays the contents of a file, when piped to grep, grep searches for and displays any strings having john in them. Now then, lets cover another file, .bash_history. .bash_history is exactly that, it is the history of all BASH commands inputted, lets display it: cat .bash_history you can pipe it to more if you wish, so you can page down it all. Nice. Now then, lets say that we want to copy the .bash_history file to bash.history.bkup: cp .bash_history bash.history.bkup will duplicate the file, so we now have two copies. well, what if we want to rename that file (the bkup) to bash.history: mv bash.history.bkup bash.history mv moves files, what we are doing is moving it from one name in your home directory (we'll cover this soon), to the same directory, under a different name. Now then, whats this home directory stuff? As specified in /etc/passwd, your home directory is the directory that you are placed in when you login. YOu usually have full permissions of this directory, lets see what your home directory is: echo ${HOME} The echo command, which we've already covered, prints the ${HOME}, but what is that? That is called a shell variable. $ means that it is a variable, {HOME} specifies that it is the variable named HOME. LEts make a new directory in your home directory, first we'll switch to that directory: cd ${HOME} cd means change directory. It changes the user's current directory for that specified. Now, lets make the new dir: mkdir TEST mkdir makes a directory, under the name TEST. Now then, lets change directories to that directory: cd TEST now we are in that directory. Nice. Now, we'll back out of this one, returning to the parent directory, or teh directory above this one: cd .. the .. specifies to move back one directory. To verify that we are in uor home dir, we will display the current dir: pwd displays the present working directory. Okay, now lets copy the backup of our history file to the TEST directory: cp bash.history TEST cp once again copies it to a location, this time a directory. cd to that directory, then do an 'ls' to see the contents: cd TEST ls -l the -l part gives a long list, without -l simply shows the file names. Okay, lets create a file, test.txt containing the string 'This is a test.' : echo "This is a test." > test.txt Now you can cat it if you wish, but the main reason we created this is to cover the next subject, chmod. 'chmod' Changes a files' permissions, which can be tricky at first, but is *IMPORTANT* for basic security. In order to do this, you need to know binary, or you can use the simpler string format, which we will use in this example, I don't want to confuse anyone this soon, if you want to know how to use chmod, check out the man page (you'll learn about this later, too). Now then, chmod follows the following syntax: chmod (permissions) (file) u means the current user g means the user's group a means all users - means take away this privledge + means give this privledge = means that this will be the only permissions this file will have r means that you can read the file w means you can write to it x means that you can execute it now then, user permissions are displayed as: -rwxrwxrwx the first bit, or character is a special one, used to run as that user, to specify a directory, etc, which we won't cover. The next three characters 'rwx' refer to the user that owns that file. The next three after that 'rwx' refer to the permissions of that owner's group. The last three characters 'rwx' spefify all other user's permissions. a '-' instead of a character means that that permission is disabled. For instance: -rwx-r--r-- Means that the owner can read, write, and execute, but the owner's group, and all other users can only read from it. Now then, lets modify our new file, test.txt so that we cannot read from it (follow me here, this is to demonstrate something): chmod u-r test.txt Now lets try to cat it: cat test.txt You should get an error basically stating that you don't have read permissions for this file. Now, lets change it back: chmod u+r and cat it again to be sure that it is changed. Nice, now lets make it to where only we can read, write, and execute to that file: chmod ga-rwx test.txt will make it to where no one can read,write,execute: chmod u+rwx will give us read, write, and execute privledges. Take this time to play around with it, learn how to use it better. Now, since we are discussing file ownerships and all, I figured that I would throw in another command, chown. Chown changes a file's owner, following the format of 'chown (user:group) (file): chown root:root test.txt Will make it to where only root is the owner. Don't do this, otherwise you will have to write a letter to root, kindly asking them to change the permissions back. For all purposes to you, you should never need to use chown. Another command you should learn how to use is rm. use this with caution, however. 'rm' removes files: rm -R ${HOME}/TEST will completely delete the contents of the directory TEST that we created earlier, plus delete the directory itself. The -R parameter means that it should operate recursively, which means to delete every file, to descend into direcotires, then remove those files, etc, etc. Now, lets say that you want to cat a user's manual, but you want to be able to scroll back a page or two wile reading (be able to go back and forth), you would: cat filename.txt | less and use the space bar to go forward, and the P key to go to the previous page. PART III. BASIC SCRIPTING Now that we have covered the basic commands, we will dive into scripting via the shell. For those of you that feel as if the shell doesn't offer anough power, I recommend you taking a look at Perl, an excellent scripting language that was designed out of a need for more power than the shell provided. One of the most important commands to remember is chmod. When dealing with scripts, you have to make the file executable. This can be accomplished by simply: chmod u+x filename.sh OR: chmod 700 filename.sh the 700 part will give the owner read write and execute privledges, while giving all other users no privledges whatsoever. Alternatively, and also more annoyingly, you can simply use the 'sh' command, followed by the script name, without needing to modify the permissions. Lets get into basic principals now of scripting, so we'll start with a simple "hello world" script. Scripts are like normal text fils, so you can use a text editor like vi, vim, joe, jed, etc. So, lets create a file called hello.sh, and place in it the following lines: # hello.sh a simple script echo "Hello World" And save it. Now, you can either chmod u+x this file, or you can execute it by: sh hello.sh However, if you chmoded it, like I suggest, you will need to: ./hello.sh Now, whats this './' stuff all about?? The answer is simple, the './' indicator means the current directory, which is similar to '..' when we were playing with 'cd'. If you 'cd ./' it will stay in the same directory. For instance, if the current directory was '/home/user', the value of ./ would be the same as typing /home/user. If you want to just execute hello.sh by just typing hello.sh, you will need to change your search path. Your search path is a variable that is defined as teh paths to search for an executable file. Instances of this are '/bin', '/usr/bin', and usually '/usr/sbin'. Now that we have the actual execution parts taken care of, lets disect the script. We shall start with the first line, which begins with a '#'. This is known in the UNIX world as a hash mark, and it is used for comments. Anything after a '#' is ignored, so you can type whatever comments you want without any worry of bothering the script. Now, for line 2, echo "Hello World". This command, echo, tells the shell to repeat, or ECHO whatever is in the parentheses, which in this case is Hello World. Now then, lets cover another important feature of scripts, the ability to force many commands onto one line: # force.sh This demonstrates teh use of the semicolon to force many commands onto a single line. echo "1" ; sleep 1 ; echo "2" sleep 1 ; echo "3" This should echo 1, wait a second, echo 2, wait another second, then eco 3 to display a nice little timer. First lets cover the sleep command, which follows the basic syntax of sleep is: sleep {# of seconds} {suffix} the suffix may be s for seconds (default), m for minutes, h for hours, or d for days. This is used in between commands that you would want a pause in, such as the timer example. Now, lets cover the purpose of this example, the semicolon ';'. The semicolon is used to seperate commands that you want exectued one after another. Now, you may question the importance of this, so I'll tell it to you: the semicolon is important, because you can enter entire scripts (if theyre short enough) on a single command line, without having to make an actual script. So in the example above, with the exception of the first line (everything behind a hash mark is ignored, remember?), if it were entered into a command prompt, it would work just the same. Plus, if you want to get really anal-retentive about it, it would TECHNICALLY be faster, as the system doesn't have to read from the HDD, it is right in memory (the commands). Now then, lets deal with making a script that will echo whatever you want it to: # argument.sh Echos an argument of the shell script echo $1 This will echo whatever you choose, you just have to use it in its own specail syntax, which is: argument.sh The text theat you want displayed. now then, you may notice that if you type: ./argument.sh text that i want it only echos text. How to remedy this? YOu remember that echo had to have quotes surrounidng it? Well the same aspect is here, you *have* to enclose it in quotes, like: ./argument.sh "text that I want" A few other important things you should know: the & symbol after a command/script tells it to run in the background. For instance, 'ls &' will preform an ls, just in the background. If you want to re-direct the output of a program to somewhere that it isnt taking up space, in the backgound, etc, you can redirect it to /dev/null, which will not return any output at all, it is a system device that is designed for uses such as this, for example: ls > /dev/null redirects the ls output to /dev/null. Also, you can spawn another shell to execute a command (has to be a command, or executable file, cant be the name of a script in the local dir, w/o the absolute path ('./'), is to use the ! symbol. For instance: ! ls however, it should be also noted that 'sh' can only execute scripts, not commands (binary executables). Now then, lets go a step beyond the "hello world" class of scripts, and lets dive into utilities, how to tailor UNIX to your liking. # delete.sh Moves files to /usr/username/trash, which is only readable by that user. mv -f $1 ${HOME}/trash As you will remember, the 'mv' command moves a file, and the -f option forces it. What this does, is it creates a "Recycle Bin" like that in Windoze, in your home direcory, under trash. Now then, what about recovering it???? # undelete.sh undeletes file specified by user. mv ${HOME}/trash/${1} ./ This is relatively simple: the mv command of course moves it, this time we'll leave the -f option off, we want to be warned if a file is going to be removed. ${HOME} means $home, or the user's home directory. ALWAYS enclose variables in {}, this keeps the values intact, so it doesnt mess up, without this, the above sript(s) won't work. Now then, the ${1} is a little new here, once again enclosed in {}. It is good practice to always enclose your variables in {}, but you only have to if they are in a path, etc. And of course ./ is the current directory. Simple stuff. Now then, lets say that you wanted to time a script to get a directory of all the files in your home directory, then to compare that listing every hour and look for changes: # ls.sh Compares a directory's contents (in this example the users home dir) for changes in a given time interval, in this case one hour. ls -l ${HOME} > ${HOME}/.ls sleep 1h ls -l ${HOME} > ${HOME}/.ls-comp diff ${HOME}/.ls ${HOME}/.ls-comp Will give a non-null output if the contents are changed. Actually, it should have the files listed that have changed as well, but lets break this down some. First line is easy, it executes an ls -l (long list of directory) in ${HOME}, then redirects it to a file, called .ls (In UNIX, any file that begins with a '.' is hidden, unless you preform an ls -a). then we wait for an hour. Then we take another 'ls -l' and redirect it to a seperate file, .ls-comp. Then, the diff command is executed, which searches for any differences in the files. If one is found, it is displayed. Otherwise, it exits with no return value. Let's play with this some though, im not happy with it: # ls.sh part 2 origional modified to send user warning of file change. while echo "Perpetual loop" > /dev/null do ls -l ${HOME} > ${HOME}/.ls sleep 1h ls -l ${HOME} > ${HOME}/.ls-comp if diff ${HOME}/.ls ${HOMR}/.ls-comp then echo "this is ignored, since it is being redirected to /dev/null" > /dev/null else clear ECHO "FILES CHANGED!" break fi done Lets start from the first line, this script invokes what's called conditional logic, which states basically that if something is true (no returned value in the instance of shell commands), then the script should do something. The first conditional logic we will use is the while statement. The while statement will continue to do what is between do and done until either it is broken out of, or the test returns a non-zero value (it returns text, whatever.). While follows: while command_that_returns_no_value do some commands done Now then, the command that we want while to test is going to be echoing something to the null device, /dev/null, which returns no output 100% of the time. This creates a perpetual loop, until we break out of it. The rest is the same, up to the if statement, which follows: if command_that_returns_no_value then do something else do something different fi the fi ends the if loop. What we are now saying is that if when we compare the diff output, if it returns no value (is true), then we want to do nothing, which in this case is another practice in using /dev/null. Now, if it returns other than zero, it means that a change has been made, which echos a nice little warning, then breaks out of the while loop, exiting the script. Well, I'm still not happy!!! insert the following line after the warning, but before break: diff ${HOME}/.ls ${HOME}/.ls-comp | mail yourusername@yourdomain This will email you the contents of the output of the differences in the files. Now, if you really want to be cool, you'll strip the break command out, so it will email you each time that a change is made, continuously running. Also, you'll take out the echo "CHANGES...." part out, which will thus print no info, and invoke it like: ./ls.sh & As you will remember, the & after a command tells the shell to execute the command in the background. Nice, now you have a free VT (or telnet session) to monitor any changes made to your directory. As I'm sure you're getting the picture of, UNIX can be tailored to fit your individual needs. The only limitation is yourself. If you feel you need something that others can't provide, or if you want to do it yourself, you CAN! And its relatively easy, as opposed to writing C code all day long. Now, you basically should get the idea of how scripting works. If not, I'll include some other scripts later on. Now though, we'll go into aliasing and linking, and modifying your search path. First, the search path: $PATH = ${PATH}:/directory_you_want_included will add an entry to the PATH variable. Place this line in your .bash_profile, or /etc/profile (for all users). This will search your direcotry for a given command, after all others. You can simnply: $PATH = /dir_you_want:${PATH} If you want it first. I prefer it to be last. Now, what about aliasing? Aliasing is used to make one "command" act as if you entered another. Type alias at a prompt to see all aliases. To add an entry: alias desired_command_name='real_command_name' will create the alias of desired to real. For instance, a common alias is alias ls='ls --color' which causes the defualt 'ls' to output 'ls --color' each time. Now, about linking. Linking is used to link one file to another. For instance, lets say you want a link in your home dir to /home/some_user/their_mp3s: ln -s /home/some_user/their_mp3s ${HOME}/kewl_mp3s will create a "directory" in your home directory called kewl_mp3s, which acts as if it were the target directory. Thus, you can 'cd kewl_mp3s' to cd to that user's mp3 directory. Well, that does it for this tutorial, check out the website above for more information such as this.