Bash scripting 101: Chapter 1: introduction





I start off pretty harshly in this introduction, i'll ease off in chapter 2, for a while at least.

The commandline: ls -la | grep 'test\.txt' || echo -e "failed\n"

would list contents (files) of the folder you are in, then use the pipe symbol " | " to send the output from ls -la, to the input of grep, (grep is a program that searches for strings/words/phrases), if there is nothing to report, "||" (two pipesymbols mean OR), and is only done if the last command , "failed" (exited with an error code, (we'll get to 'error codes' too)) then print to the screen "failed"

so basically above i'm saying:

  1. list the files in the folder/directory i'm in (" ls -la ")
  2. give the list to grep (" | ")
  3. grep, see if there is a file named test.txt, if there is, (" grep 'test\.txt' "), the backslash before "." ie the "\." is simply because grep uses regex (more about that later) in which "." means "any character here" and thus we need to 'escape' the "." (period), if there is a line containing test.txt print it out...
  4. OR ("||")
  5. print "failed" to the screen, the screen is usually stdout (short for standard out) and use the built-into-bash command "echo" to do this.
The -e after echo means "use escaped characters" and is a good idea to get used to, it increases the "power" of echo immensely, and also helps if/when you start with perl.

The "\n" part is simply an escaped (the backslash) command "\n" means "put a newline here"

so if test.txt exists you'll get something like:
ls -la |grep 'test\.txt' || echo -e "failed\n"
-rw-r--r-- 1 username groupname 24 Feb 15 16:39 test.txt
if it doesn't exist, you'll get something like: ls -la |grep 'test\.txt' || echo -e "failed\n"
failed
Now that's ok to type in, but as the commandlines get longer you may want to avoid typing it in.

You might want to keep it around for later and be able to do it with a single simple command.

Enter shell scripting: "a shell script is basically just a list of commands you could use at the command prompt, all put into a file"

So how do i put it into a file?

Well you can use a text editor (recommended way) like VI(m) which personally I don't like(but am trying to learn anyway), mcedit (part of mc midnight commander) or pico (part of pico pine email package) then there is joe, emacs and a multitude of other text editors, i use mostly mcedit, nedit(xwindows) and pico.

you can also go geekish to impress your windows friends and do it on a command line:

echo "ls -la |grep 'test\.txt' || echo -e \"failed\\n\"" >> test_txt_finder;chmod 700 test_txt_finder

aww man..what'd ya do now???

looks complex? it's not! :-)

  1. echo (first doublequotation (") to last doublequotation (")) ..echo/print this(what ever is in between the two doublequotation marks) to the screen
  2. "ls -la |grep 'test\.txt' || echo -e \"failed\\n\"" we've covered that, compare the differances and you'll see i only added \ 's which are as you notice backslashes, they are needed cause we have " in the middle of the line and to bash, quotations are "on" "off" toggles so we use \ to make sure bash doesn't "interpret" them. We also need to do this for the \n part or we'd be telling bash to interpret the "\n" for the first "echo" if we don't do the escape for it we get a linebreak after "failed" inside the program FILE, and we want that linebreak on screen when we run the program, not INSIDE the program.
  3. >> this means send the output to, appending to (there is also > which overwrites current content) file
  4. ; this separates commands, it's the same as hitting enter and entering a new line
  5. chmod 700 test_txt_finder change this file so it's -rwx------ or read-write-executable
it won't run when i type in test_txt_finder, ...nope it won't it lacks one, potentially 2 things to run as it is.

one is that you might not have your folder in your path, you solve this by typing ./test_txt_finder

the other is that you haven't told the script what "interpreter" to use

you can do this a couple of different ways:
bash -c ./test_txt_finder is one way

the other way which is prettier and less messy is using a "she-bang line"

a "shebang line" is simply the first line in the script file, into which you have put what interpreter you want to use.

we want to use bash, so for me that means /bin/bash

i put #!/bin/bash onto the first line of the file

at this point you may want to use "whereis bash" or "which bash" to find the path for bash

so open up the file in a text editor and enter the shebang line if you feel like it, if not,you can use 'bash -c ./filename' from now on

can i do it in the "impress win users" way? you sure can!

remove the old file and try:
echo -e '#!'$(which bash)"\n\nls -la |grep 'test\.txt' || echo -e \"failed\\\n\"" >> test_txt_finder;chmod 700 test_txt_finder

or if you read all the text above properly..see if you can figure out the way to do it(remove file, create new one with shebangline, put "program into it" ) on one commandline (there are at least 2 ways)

  1. echo -e first doublequotation(") to last doublequotation(") echo/print this(what ever is in between the two doublequotation marks) to screen
  2. '#!' single quoted #! to be echoed ie..put #! into the file
  3. $(which bash) uh oh..new stuff!!! ...$() simply tells bash, execute this command inside the ()'s and THEN do something with the result. It's pretty much the same as using backticks `command here`
  4. \n\n (well we don't want the script on the she-bang line)
  5. \ notice i had to put in one extra backslash at the end ?...that's cause we are "interpreting the line twice"
is it getting obvious why a text editor is to prefer?

anyway before we go into the text editor part we need one more topic..here-now files:

cat - concatenate files, is useful for many things, it's not the best to use to dump small text to the screen but we'll do that too, however it can be used to make "here now" files (ie as a small text editor)

cat << \#myend >> test_txt_finder

will let you add to the end of your file, line by line, you exit it by entering #myend (the backslash in the "cat command line" is to make bash leave the # alone, # in a bash script means "comment, don't interpret" so we are making a comment at the end of the file as we exit, but it's better than getting a "command unknown" or similar error

basically you are telling cat "receive my input(stdin) and send it to that output (test_txt_finder) until i give you a "#myend" on it's own line

i'm not going to explain these two last lines below, since it's not something you need to do, they are simply "impress windows users" lines:

echo -e '#!'$(which bash)"\n" > test_txt_finder;chmod 700 test_txt_finder;cat << \#myend >> test_txt_finder;./test_txt_finder

this one you need to enter these two lines below on a line each: at the ">" prompt you'll get
ls -la |grep 'test\.txt' || echo -e "failed\n"
#myend

the other way is, do it all on one command line:

echo -e '#!'$(which bash)"\n\nls -la |grep 'test\.txt' || echo -e \"failed\\\n\"" >> test_txt_finder;chmod 700 test_txt_finder;./test_txt_finder

end of that silliness

ok, you said chapter two was gonna be easier, and thank YOU for that, but why did you do all that backslash escaping and different quotations marks? aaaah, well you see, in bash they kind of mean different things, you have:

pretty exact "
even MORE exact '
the differance between them is among other things that they handle \, $ and similar characters differently (which gets important when you get into variables further on).
you can look up the differances with "man bash" as well as "help"...

hey i'm reading this tutorial kinda thing, whadda i want with man files??? you want to read them is what you want, for every command i use in my examples i suggest a "man commandname" and at least skim the commands syntax, purpose, and the switches i use, it's a shell scripting 101, not a "whole frigging OS 101" if you need a whole OS manual..go forth and google in peace

onto the text editor kinda way :-)




Bash Scripting101: home/index Bash Scripting101: Chapter 2: Hello World(first real shell script)



w0nderer