The Text-User Interface

Using applications, configuring, problems
Message
Author
Bruce B

Teaching on a gradient - learning on your own

#21 Post by Bruce B »

Teaching on a gradient - learning on your own

Many people associate learning with pain. I expect if you are even reading Chapter 21, you aren't one of these types of people. Or if you are, you have enough determinism and desire to learn not to let the pain association be a deterrent.

I love learning, but I really don't want anyone teaching me at a gradient too steep for me ( too painful ).

At this point of your learning experience, I'd like to state or restate, some of what I'm doing.
  • 1) I'm trying to gradually help you set up a more friendly and powerful TUI environment than the one you started with. In doing this I might find myself a bit a cross-purposes with another objective, which is;

    2) teaching bash scripting on an easy to learn gradient.
Obviously, I want you working in as friendly and powerful environment as possible. We build this environment gradually.

If you find some file unexplained and over your head, it is very possible, I'm trying to help with number (1). Explaining every aspect of a file may be on too steep a gradient for number (2), it might remain unexplained for this reason.

If you run into a situation like this, I advise; do not try and understand the file or procedure, if it is too hard, especially if stands to reason its purpose is in category number (1).

Two requisites defined for the bash programmer
  • 1) Understanding the directory tree and files

    2) File management skills
Two requisites explained

If you don't have a solid grasp of the directory tree and files, your file management skills will be lacking. Your programs will not be as expansive as they otherwise could be. Lots of what we might want to do in scripting pertains to file management.

Optional self-learning assignment

( Midnight Commander is a powerful file manager and just by using it, you will become gradually more familiar with Linux' directories and files. ) ( have you noticed with mc, you don't need to extract the .zip package and many other packages to copy files out of them? )
  • 1) download the package tree.zip, its contents are one binary named tree and one text file called tree.txt which is the --help for tree.

    At this point, no instructions should be needed. Simply put the binary file tree it it's appropriate directory and the documentation tree.txt in its appropriate directory.

    2) using the Internet search, find a page which helps you to learn Linux default or basic directory tree. Read it and learn the basics, ( if you need the instructions at all ).
~

Chapter 21 - Teaching on a gradient - learning on your own

~
Attachments
tree.zip
contents : binary file - tree : text file - tree.txt
(16.25 KiB) Downloaded 1878 times
Last edited by Bruce B on Sat 04 Jul 2009, 14:01, edited 1 time in total.

Bruce B

Formatting and colorizing text - a preview

#22 Post by Bruce B »

Formatting and colorizing text - a preview

This chapter is a preview for the next chapter, which will make very easy work of colorizing and formatting your script's on screen output.

Tastefully adding color to your text output, can add a professional look to your scripts.

When and where to color your text will be up to you.

Showing you how, and how to do it with ease, is my job.

See picture for preview.

~

Chapter 22 - Formatting and colorizing text - a preview
Attachments
colorizing-text.png
Demo - colored text on the console
(2.57 KiB) Downloaded 3095 times

Bruce B

#23 Post by Bruce B »

Displaying text with our scripts

The echo command is internal to our command processor, bash. How to know?

Type help and see if echo is in the list

In Puppy, the echo command may also be an external command. How to know?

which echo
and/or
ls -l /bin/echo

The rule is: an internal command will have precedence to an external one. However, if for some reason we wanted to use the external one we could, if it exists, by specifying the full path;

/bin/echo

Using echo

We typically use echo for displaying something to standard output (or in redirection). I want to emphasize echo's abilities go beyond what it is typically used for:

How about math? Try this command:

echo $[5+23]

Displaying files, try this:

echo *

Using quotes as a safety net

Until we learn the ins and outs and the peculiarities of echo, I recommend quoting what you wish to display. By quoting your intended output in your script, you are more likely to have the results you intended.

echo "My last directory was: $OLDPWD"

echo's default is to give a line feed at the end of the line. Remember from earlier the 'eol' is a non visible character, but it affects the formatting of our output.

echo -n says don't use a line feed. Let's try the above command with echo -n as follows;

echo -n "My last directory was: $OLDPWD"

echo -e : means enable interpretation of \ escape characters, which we need for coloring

Introducing cecho

If we type cecho on the command line, bash tells us:

cecho: command not found

Good, this is an available command name. We will call the our new command: cecho
It means; color echo

cecho usage:

cecho color "text for screen display"

for no new line;

cecho color "text for screen display" n

The cecho function, displayed in its present form, but I want to refine some things before you install it. The refinements and install instructions, will have to wait until next chapter. (or the next, next) Sorry. I'm starting to learn what they mean when saying, "Rome wasn't built in a day."

Code: Select all

cecho() {

    case $1 in

        black)    echo -e$3 "\\033[1;30m""$2"
        ;;   # black

        blue)     echo -e$3 "\\033[1;34m""$2"
        ;;   # bright blue

        cyan)     echo -e$3 "\\033[1;36m""$2"
        ;;   # bright cyan

        green)    echo -e$3 "\\033[1;32m""$2"
        ;;   # bright green

        magenta)   echo -e$3 "\\033[1;35m""$2"
        ;;   # bright magenta

        red)      echo -e$3 "\\033[1;31m""$2"
        ;;   # bright red

        white)    echo -e$3 "\\033[1;37m""$2"
        ;;   # bright white

        yellow)   echo -e$3 "\\033[1;33m""$2"
        ;;   # bright yellow

        black0)  echo -e$3 "\\033[0;30m""$2"
        ;; # black normal

        blue0)     echo -e$3 "\\033[0;34m""$2"
        ;;   #  normal

        cyan0)     echo -e$3 "\\033[0;36m""$2"
        ;;   #  cyan normal

        green0)    echo -e$3 "\\033[0;32m""$2"
        ;;   #  green normal

        norm*)     echo -en "\\033[0;39m"
        ;;   # normal normal

        magenta0)  echo -e$3 "\\033[0;35m""$2"
        ;;   #  magenta normal

        red0)      echo -e$3 "\\033[0;31m""$2"
        ;;   #  red normal

        white0)    echo -e$3 "\\033[0;37m""$2"
        ;;   #  white normal

        yellow0)   echo -e$3 "\\033[0;33m""$2"
        ;;   #  yellow normal

    esac

}
~

( the function works, but I think I can do better )

Chapter 23 - Displaying text with our scripts

Bruce B

The case statement, escape sequences

#24 Post by Bruce B »

The case statement, escape sequences

Code: Select all

case $1 in

    blue)     echo -e$3 "\\033[1;34m""$2"
    ;;   # bright blue

    green)    echo -e$3 "\\033[1;32m""$2"
    ;;   # bright green

esac
Define 'case $1 in' in English; "In case my first argument matches my criteria, (blue or green), then do the commands in my criteria. Otherwise do nothing."

------------------

What does blue mean?

It is a search criteria for $1

Literally, to bash, blue means: echo -e$3 "\\033[1;34m""$2" , because we made it mean that, you see how?

I think 'blue' is both easier and more intuitive, than the full bash command, thus the reason for the function I posted (and will refine). Make it easy!

-----------------

How many arguments are in this command?

cecho blue This is my text to display n

If we don't consider cecho as an argument, which it is. (The command name is $0) We have 8 arguments.

But blue only accepts 3 arguments. Very important to understand is; how to make 8 arguments into 3 arguments, a basic answer is: with quotes;

cecho blue "This is my text to display" n

arg1 = blue
arg2 = This is my text to display
arg3 = n

blue) echo -e$3 "\\033[1;34m""$2" ;;

The 3 arguments explained;

$1 is our search criteria name and our actual color
$2 is the full quoted text
$3 is the optional 'n' argument, which is appended to echo -e, thus making echo -en

If $3 doesn't exist, it is nothing, of null effect. If it exists as 'n', it tells cecho not to add a new line.

The \ is the character I call the do something different character. In the case of \\, I interpret it as saying do something different to the do something different character :)

Combined with the echo -e switch, the full string, echo -e "\\033[1;34m" changes the text attributes to boldblue.

The double ;; signals the end of the particular matched case criteria execution - and all execution in the case statement.

~

Chapter 24 - The case statement, escape sequences

Bruce B

#25 Post by Bruce B »

A function based program

In this chapter we will work together and build a function based program. Programming begins with an idea. I have an idea that I would like you to be able to easily, very easily, as easy as possible make practice scripts.

I will title the program 'fun' and if that name doesn't suit you we will write it so you can change its title.

Scripts run commands. Scripts read from top to bottom. When I build a completely function based script, the first command is at the bottom. Putting it on the bottom means bash has read the entire script, (its functions) before any program execution begins.

The 'explanation formatting' in this chapter will be first the script, followed by explanation.

Code: Select all

#!/bin/bash

main() {

	echo

}

main
We now have a complete script that only echoes a linefeed. The reason for the echo command is bash doesn't want us to leave our functions empty. Echo doesn't fill our need, rather a bash demand.

Code: Select all

var() {
	
	wrkdir="/root/bin"
	cmd=`basename $0`
	test "$wrkdir" = ""  && "echo variable wrkdir is empty" && exit
	test ! -d $wrkdir && "echo working directory doesn't exist" && exit
	cnt="0"
	quit="1"

}
var is the function we use to define and process variables

wrkdir : our working directory, make sure our files are always in that directory

cmd : is the stripped $0 , using basename we convert it from: /root/bin/fun to: fun

tests : unnecessary used as example. but, sometimes wisdom says to test condition prior to execution of other commands

cnt : we set our counter to zero, it will be used in the next function : mkfile

quit : quit will also be used in the next function : mkfile

Code: Select all

makefile() {

	cd $wrkdir

	while [ "$quit" = "1" ] ; do
		
		cnt=`echo $[$cnt+1]`
		if [ ! -f ${cmd}$cnt ] ; then
			
			file="${cmd}$cnt"
			echo "#!/bin/bash" > $file
			echo -e \\n\\n >> $file
			chmod 755 $file
			$guieditor $file &
			quit="0"
			
		fi

	done							
	

}
cd to our working directory

begin the execution of the while loop. while loops as long as our condition is true, which we've define is the variable quit=1, if something happens where the variable quit equals anything else, the loop stops running

cnt : note we increment it by a numerical value of 1 each time the while statement loops

if [ condition check ] : we are looking for a file that doesn't exist. the filename is fun# , which is the variable cmd plus the variable cnt

echo -e \\n\\n >> $file : adds two linefeeds

when we find a fun# file that doesn't exist, we make the new file, give it executable attributes, and open it in our 'guieditor'

all this happens by typing in one command : fun

here is our function based script put together in working form:

Code: Select all

#!/bin/bash

main() {

    var
    makefile

}

var() {
    
    wrkdir="/root/bin"
    cmd=`basename $0`
    test "$wrkdir" = ""  && "echo variable wrkdir is empty" && exit
    test ! -d $wrkdir && "echo working directory doesn't exist" && exit
    cnt="0"
    quit="1"

}

makefile() {

    cd $wrkdir

    while [ "$quit" = "1" ] ; do
        
        cnt=`echo $[$cnt+1]`
        if [ ! -f ${cmd}$cnt ] ; then
            
            file="${cmd}$cnt"
            echo "#!/bin/bash" > $file
            echo -e \\n\\n >> $file
            chmod 755 $file
            $guieditor $file &
            quit="0"
            
        fi

    done                            
    

}

main
Please note the program flow. One call to main. Main makes one call to each function. Each function returns to main for its next command. When main has no more commands, the program quits.

fun is attached, don't copy and paste this one, you know the drill

From now on, when you want a practice script simply type fun.

~

Chapter 25 - A function based program
Attachments
fun.zip
Contents : script called fun
(459 Bytes) Downloaded 1928 times

Bruce B

A conventionally formatted script

#26 Post by Bruce B »

A conventionally formatted script (with explanations)

Code: Select all

#!/bin/bash
# filename : base-name
ARGUMENTS=`echo $0 | tr "/" " "`
echo "Command name with path is: \"$0\""
for VAR in $ARGUMENTS ; do
	CMD_NAME=$VAR
done
echo "Command name without path is: \"$CMD_NAME\""
This is a short conventionally formatted bash script. The variables are in CAPS. Note how much different it is than the function based script.

It's purpose is to do what basename does, find the name of the command minus the path.

For fun we also display some information on the screen.

Line2)
  • A comment saying what we name the script
Line3)
  • ARGUMENTS=`echo $0 | tr "/" " "`

    we echo $0 through a pipe to tr. This is the first time you've seen tr. tr will replace one character with another. We replace / character with a space.

    the on screen output would be: root bin base-name

    the space character is used as an argument delimiter or separator. this is how we will use it and why we replaced the / with a space

    we use the backtick character to direct the output to the variable ARGUMENT
Line4)
  • echo "Command name with path is: \"$0\""

    displays like this:

    Command name with path is: "/root/bin/base-name"

    We use the 'do something different character \' in this scenario to get our quotes to display
Line5 to Line7)
  • for VAR in $ARGUMENTS ; do
    CMD_NAME=$VAR
    done


    For our variable VAR read each argument and do with the argument as instructed

    Instructed to put each argument value into the variable CMD_NAME

    The iterations, what happens on each pass through the loop;

    VAR=root
    VAR=bin
    VAR=base-name
    # our file name

    for has done as told, it processed all our arguments, leaving us with a VAR set to our filename. The path has been removed.

    done is part of the for loop syntax, it literally means; done
Line8)
  • echo "Command name without path is: \"$CMD_NAME\""

    displays on screen:

    Command name without path is: "base-name"
Optional assignment

Look at this file for the purpose of seeing what a large script with comments looks like: /etc/rc.d/rc.shutdown

As far as the code in this chapter, we have no future use for it. This chapter's purpose is presenting and reinforcing theory. However, feel free to download the script.

~

Chapter 26 - A conventionally formatted script (with explanations)
Attachments
base-name.zip
(288 Bytes) Downloaded 1905 times

Bruce B

cecho

#27 Post by Bruce B »

cecho

Package description:

Code: Select all

Archive:  cecho.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
     1304  07-04-09 16:50   colors.txt
     1304  07-04-09 16:47   .clr
     8356  07-04-09 16:52   tput
 --------                   -------
    10964                   3 files
Usage modification from previous instructions
  • To reset colors to normal in your scripts use this command: cecho reset
Theory
  • Variables easily get passed up. The variables we set in profile.local get passed up to our X terminal emulator.

    Functions don't get passed up easily.

    Cecho is a (the only) function of a file .clr

    In your scripts you could simply copy the function to your script. Also because variables get passed up, we can source .clr with a variable or source it directly.

    Our script could have this command

    Code: Select all

    source /root/bin/.clr
    If we set a variable called clr which sources .clr, it could use this command:

    Code: Select all

    $clr
Installation instructions
  • put color.txt in your doc directory, use it for reference, it is an exact copy of .clr
    put .clr and tput in the /root/bin directory

    add these lines to /root/.bashrc and to /etc/profile.local

    export clr="source /root/bin/.clr"
    $clr
Usage examples:
  • cecho red "This is a line of red text"

    cecho blue "This is a line of blue text"

    cecho green "Color green" n # green text, no newline

    cecho reset # resets font attributes to normal.
Optional Assignment
  • after installing the cecho components, use the utility fun and practice with the echo and cecho commands, displaying text on the monitor, from your script commands.
~

Chapter 27 - cecho
Attachments
cecho.zip
(5.09 KiB) Downloaded 1898 times

Bruce B

hardinfo and lshw

#28 Post by Bruce B »

hardinfo and lshw

I'd like to introduce you to some useful utilities in the next few chapters. In this chapter we will learn hardinfo and lshw

Instructions for hardinfo

cd /root/doc
hardinfo --generate-report --report-format html > hardinfo.html


Make it easy, copy and paste the long line to the command line. We learn through repetition, I'll repeat the copy and paste.
  • * Highlight the long line, leave it highlighted

    * change to mrxvt

    * to paste; shift insert or press middle mouse button, (hit enter) then; wait until hardinfo generates its report and performs its benchmarks, it takes some time.
Instructions for lshw

If you don't have lshw, download it from this post. You know the drill to install it. Then;

cd /root/doc
lshw -html > lshw.html


Remember the bookmark you made in your favorite browser? Open the directory /root/doc and view your new reports.

~

Chapter 28 - hardinfo and lshw

Bruce B

#29 Post by Bruce B »

An unknown file type

I download a file referenced in this forum post: Slitaz' floppy boot disk boots Puppy

The file name is: floppy-grub4dos

Often when we download a floppy image, the extension is;

img : for floppy image ( sometimes hdd image )
or
imz : for bziped floppy image

There are no solid rules on the extension naming conventions with these images, just common conventions.

floppy-grub4dos
has no extension - this is perfectly fine for me and for our lesson.

Learning more about the file

ls -l floppy-grub4dos

gives me this output:

-rw-r--r-- 1 root root 1474560 2009-07-06 00:51 floppy-grub4dos


The byte size 1474560 is precisely what one would expect for an uncompressed floppy image

file floppy-grub4dos, gives;

x86 boot sector, code offset 0x2e


hexedit floppy-grub4dos; for a visual interface

The boot sector, the first 512 bytes, doesn't look like a DOS boot sector. I think the floppy image is a Linux format.

Next I want to mount it and look at it in human readable form.

In order to mount floppy-grub4dos, a character device, we set it up on a block device, /dev/loop?

losetup -f
: prints an available device

/dev/loop5, then the commands:

losetup /dev/loop5 floppy-grub4dos
mount -t ext2 /dev/loop /mnt/data


Note the file is mounted rw (read-write) we can modify it and save our changes. We cannot however increase the size.

The tree, in human readable form

|-- boot
| |-- btmgr.gz
| |-- etherboot
| |-- gpxe
| |-- memdisk
| |-- memtest
| |-- nssi.igz
| `-- plop.gz
|-- default
|-- grldr
|-- lost+found
|-- menu.lst
`-- slitaz.xpm.gz
2 directories, 11 files


umount /mnt/data
losetup -d /dev/loop5


Anthing learned?

Here is a list of the utilities you've been introduced to or reintroduced to in this chapter.

losetup
umount
mount
file

hexedit ( needs a better hex editor than what Puppy comes with )
ls

Optional assignment - You can do everything in this list.

~

Chapter 30 - an unknown file type

Bruce B

#30 Post by Bruce B »

Black holes

For the purpose of this chapter, and not being an astronomer, I'll define a black hole as something that tends to absorb light. The light being your consciousness and the black hole being what tends to leave you in the dark.

In computing, I'd call the command line itself, a black hole for many. The Windows registry for others. Also the MBR.

I hope to shed some light on the MBR (Master Boot Record) in this chapter.

I've read forum topics where the OP had a bad MBR, or thought he had a bad MBR. Then from 10 to 30 or more follow up posts trying to help the OP.

On your partitioned hard disk your MBR will be the first physical sector of the hard disk.

Introducing dd - a copy / convert command.

Save a copy of the MBR:

dd if=/dev/hda of=hda.mbr bs=512 count=1

Restore the MBR from the copy:

boot to the command line
cd to the location of hda.mbr
the commands listed below are a bit more than necessary, but we really want to do this right or not at all.

sync
dd if=/dev/hda.mbr of=hda.mbr bs=512 count=1
sync
reboot


(sync flushes pending buffered writes held in memory)

Tips:

I can't tell you if it is /dev/hda, /dev/sda or something else, not with Puppy. Puppy changes. I can (later) tell you how to tell the Linux designation for your hard drive.

It is good to have a copy of your MBR. If the copy is of /dev/hda, it is best to save a copy on another device. The reason why is; if your hda MBR really goes bad, you may not even be able to access the drive to get to your backup MBR.

So, save it on a floppy disk, USB stick or some place other than hda. But also save it on /dev/hda because in most cases hda will be accessible and you can use the backup MBR from it.

Why the MBR goes bad


Usually, it never changes. It shouldn't ever change. But when we install various operating systems, we run the risk of it changing the MBR in a way we don't want to, or a dumb install routine changing it in way we really don't want. ( discounting the very unlikely event that our own stupidity isn't the cause )

When to save a copy of the MBR

Immediately after every time we modify our partitions. Especially primary partitions.

If you end up not deleting an earlier MBR, need to restore and become confused which backup to use, use the ls command like this:

ls -l <filename>

View the date and this will help determine the date of your backup, by reading the date in ls output - it should correspond with the date you partitioned.

We could also make dated backups. But we've not been introduced to the Linux date command yet.

Optional Assignment

Don't do the example exercises, (commands in blue), at this point.

Read http://en.wikipedia.org/wiki/Master_boot_record and learn a little more about the MBR, don't try and digest everything, too hard.

~

Chapter 31 - black holes

Bruce B

Simple math

#31 Post by Bruce B »

Simple math

Sometimes we want to perform simple math on the command line;

add, divide, multiple, subtract - then have the command prompt return after the command.

Introducing the external command: bc

bc is an extremely powerful calculator - powerful enough just using it could become a study in and of itself

Introducing: shift

shift is an internal bash command. It moves the variable string from right to left. Here is an example:

args = these are my arguments

$1 : these
$2 : are
$3 : my
$4 : arguments


The 'shift' instruction makes this change

args = are my arguments

$1 : are
$2 : my
$3 : arguments


Note how $1 disappeared and the other arguments are re-designated right to left.

Code: Select all

case ${1} in

	a*)  shift ; echo ${1}+${2}  | bc -l ;;
	d*)  shift ; echo ${1}/${2}  | bc -l ;;
	m*)  shift ; echo ${1}\*${2} | bc -l ;;
	s*) shift ;  echo ${1}-${2}  | bc -l ;;
	*) echo "a*dd | d*iv | m*ul | s*ub" ;;

esac
You've been introduced to; the case statement, shift, bc, | and echo

Curly braces {}

{ : begin
} : end

In this example, the curly braces are way overdone, we use them to make sure bash doesn't misinterpret where a variable ends. The $ says where it starts, but where does it end?

Is the variable $1 or is it $1- ?

The curly braces define ${1} as exclusive from any character immediately following.

The wildcard *

In this case statement, anything which starts with the letter a is a match because of the wildcard *

a, add, and advertise all mean the same thing.

If our first argument does not start with a,d,m,s ; the * at the end does match, and prints out a message and returns our command prompt.

This simple, even simplistic script does what it's made to do and even handles floating point math.

We use $1 to determine if we want to add, divide, subtract or multiple. I use the shift command mostly for demonstration. We could also not shift and use arguments $2 and $3 for processing the math. Makes sense? I hope.

Usage examples

math a 8 81
math d 124 2
math s 9 3
math m 1024 1024


Running totals:

double click the result and paste it into your next calculation

The purpose is . . .

. . .making things easier when we want simple math

Mandatory Assignment

Make a new utility called math by using our easy copy and paste method; (newsh)

Practice with it some

~

Chapter 32 - Simple math
Last edited by Bruce B on Mon 06 Jul 2009, 14:48, edited 1 time in total.

Bruce B

From image file to floppy disk

#32 Post by Bruce B »

From image file to floppy disk

Don't do exercises in this chapter unless you want and have reason to do the exercises.

A floppy disk is a physical object which we cannot download. We can of course download a floppy image.

First thing to do after downloading the imagefile.img is check its size with the ls command, using the -l switch, like this:

ls -l imagefile.ext

If the size is 1474560, it's likely ready to use.

If it is smaller, then use file to learn more, maybe it's compressed with bzip2, or something else, file will tell you:

file imagefile.ext ; if output is;

bzip2 compressed data, . . .

There you have it, it needs to be decompressed prior to use

bzip2 -d imagefile.ext

Then, again;

ls -l imagefile.ext

If byte size is 1474560, this is the size we generally expect prior to copying to floppy.

You can run file again and see what file thinks of it

file imagefile.ext

We know the name of our image file, what's the name of our floppy device?

Considering how Puppy changes, I dare not say, lets see if we can learn from Puppy.

cat /etc/fstab ; if you see something like the line below, Puppy thinks your floppy is /dev/fd0, so that's what we will use.

Code: Select all

/dev/fd0      /mnt/floppy  auto     noauto,rw              0 0
More on our dd (copy / convert) command. To copy the image file to the floppy disk, we could;

dd if=imagefile.ext of=/dev/fd0

if : infile
of : outfile

If we used our noggins, we put the floppy disk in the drive before running the command.

dd by default fails on errors, I think this is what we want, because if our outfile, contains errors we want to know about it and probably not use that floppy disk, (our outfile)

Suppose we want to give dd more exacting and explicit instructions. We could tell it to behave differently, according to our specifications.

We know the size of the file : 1474560

The default sector size for a floppy is : 512 bytes

Our new calculator 'math' will tell us how many sectors.

math d 1474560 512

answer is 2880

Our modified image to floppy command could become:

dd if=imagefile.ext of=/dev/fd0 bs=512 count=2880

If we planned more image to floppy copying, we could make a very simple script;

Code: Select all

#!/bin/bash
# filename : image2floppy
[ ! $1 ] && echo Missing argument && exit
dd if=$1 of=/dev/fd0 bs=512 count=2880
To make a respectably fair erase on a floppy disk containing sensitive information;

Code: Select all

#!/bin/bash
# filename : erase-floppy
dd if=/dev/zero of=/dev/fd0 bs=512 count=2880
dd if=/dev/random of=/dev/fd0 bs=512 count=2880
Destructive commands

I think it imperative to discuss destructive scripts. The above two script examples will irreversibly destroy any existing data on the floppy disk.

If you distribute your work, take the few minutes necessary and make some conditional checks as a part of your script.

We could advise the user the existing data will be destroyed and get permission FIRST.

We could optionally also offer to mount the disk and display the contents FIRST.

Doesn't this go without saying? The answer is unfortunately, a resounding NO!

Assignment - just read the chapter, which you've just done.

~

Chapter 33 - From image file to floppy disk

Bruce B

top

#33 Post by Bruce B »

Chapter 34 - top

Part of the curriculum in this series is introducing you to various command line utilities. In this chapter, I introduce you to top.

Assignment - open mrxvt and type top, then enter.

( q key to quit )

This is the end of your introduction to top. I have nothing to say about it, because there is something better.

htop

We will install a much more useful (yet quite small) utility called htop.

After you have installed htop, repeat the above assignment;

open mrxvt and type htop, then enter

It should be obvious to you why I've nothing to say about top and added htop.

I'll leave it to you to learn htop and read the text man page.

I do however . . .

. . . wish to teach you one aspect of htop, because it can get you out of trouble with a locked up application. And the technique described below is not particularly intuitive.

Suppose an application locks up and uses all available X resources. There is a GUI application somewhere in the menu to kill the offending application. But the GUI is so locked up, you cannot even access the menu.

I've seen posts where the Ctrl+Alt+Backspace key is the recommended way to leave X as if it were the standard way of operating Puppy. I cringe.

Left-Ctrl+Left-Alt+F2 will give you a terminal without crashing X or the application.

After logging in to your new terminal, run htop.

In htop, highlight the offending application. Then the F9 key, try and shutdown the offending application in this order;

15 SIGTERM

if that doesn't work, then;

9 SIGTERM

After closing the offending application, close htop and optionally logout of the terminal by typing exit.

Then;

Left-Ctrl+Left-Alt+F3 to return to your X session.

The instructions here probably won't have full meaning until you download and install htop.

Assignment - Please consider installing htop as highly recommend
  • 1) download htop.zip

    2) using mc, place htop and htop.txt in their appropriate directories

    3) open htop and familiarize yourself with it

    4) practice leaving X to a terminal and returning to X as described

    5) practice using htop for the purpose of conceptualizing how it is used to close an offending X application from the TUI
~

Chapter 34 - top
Attachments
htop.zip
contents: binary file - htop, man page - htop.txt
(40.71 KiB) Downloaded 1862 times

Bruce B

Install Medit with Midnight Commander

#34 Post by Bruce B »

Chapter 35 - Install Medit with Midnight Commander

In this chapter, we will practice using some Midnight Commander features. Also, install a great text editor / programmers editor called 'Medit'.

Medit isn't included with Puppy, but it is a part of its Official Repository.

We will do everything with Midnight Commander from downloading the medit archive to installing it.

Here are the steps:
  • 1) open mrxvt and mc

    2) connect to ftp.ibiblio.org with Midnight Commander, ( F9 + FTP Link . . .)

    3) type ftp.ibiblio.org then enter

    4) navigate the FTP server to this directory:

    /pub/linux/distributions/puppylinux

    5) bookmark it for future use ( left-Ctrl + \ )

    6) find this file in the /pet_packages-4 section: medit-0.9.2.pet

    highlight it; F5 to copy it from the FTP server to the directory of choice on your computer, (the pane not connected to the FTP server)

    When done: cd - to disconnect from the server

    7) if you installed the extension I posted in an earlier chapter, all you need do is highlight your local copy of medit-0.9.2.pet and it will open in a virtual archive

    8) using Midnight Commander's copy (F5), install Medit according to the archives directory tree, which in this case will be in /usr

    Previously we've been putting all files in our custom directories. In this lesson, I want to show you how to manually install a prepared pet package. So, we will use /usr according to the package tree.
If you do it right everything will be perfect, except your newly installed package will not be registered.

~

Chapter 35 - Install Medit with Midnight Commander . . .

. . . to be continued in Chapter 36

Bruce B

#35 Post by Bruce B »

Chapter 36 - listing files contained in a pet archive

In Chapter 35 we installed medit-0.9.2.pet. We don't however have a listing of the files installed. Not yet anyway.

When we make scripts or aliases we want to give them meaningful names which are easy to remember.

Suppose I pick a name like listpetfiles, it's descriptive, but a little long.

If we use tab-completion, all we need do is type listp, then hit the tab key for the rest of the file name.

Well, we are going to call our next script listpetfiles, if you want a different name, you don't need to rename it at all.

Introducing ln - making symlinks
  • Suppose you would rather use the name showpetfiles, you can make a 'symlink' like this:

    bin ( our alias for cd /root/bin )
    ln -s listpetfiles showpetfiles

    Doing so, it doesn't matter if you type showpetfiles or listpetfiles, the results are the same.
Introducing our script

Code: Select all

#!/bin/bash
# name: listpetfiles
# purpose: catalog contents of .pet archives
# to our personal doc directories

main() {

    var "$1"
    makelist

}

var() {

    [ ! $1 ] && echo "Argument missing" && exit
    [ ! -f $1 ] && echo "$1 doesn't exist" && exit
    echo "$1" | grep "\.pet$" >/dev/null
    if [ "$?" != "0" ] ; then
        echo -n "$1 doesn't seem to have a "
        echo ".pet extension quitting now"
        exit
    fi

    fn=`basename $1 .pet`
    outdir="/root/doc"

}

makelist() {


    <${fn}.pet gzip --decompress | tar --list \
    | tee ${outdir}/${fn}.txt


}


main "$1"

Script explanation
  • Another function based script

    The function var is used for sanity checking variables and setting variables
[ ! $1 ]
  • is a test to see if $1 does not exist. [ is a test command, ! means not , ] signals end of test
    our test is true if there is no command line argument, the subsequent commands execute, because the condition is true
[ ! -f $1 ]
  • -f says we are looking for a file with the same name as the content in $1
    ! means not

    if the filename in $1 does not exist the test is true and the subsequent commands execute
echo "$1" | grep "\.pet$" >/dev/null
  • here we pipe the argument $1 to the grep command by using echo. we are looking to see if arg1 ends in .pet

    we don't want on screen output so we direct the output to the device >/dev/null

    running the command therefore displays nothing
if [ "$?" != "0" ] ; then
  • this command followed the grep pipe. grep either found .pet at the end of the argument or it didn't

    if grep found .pet at the end of the file, it exited with an exit code of 0, meaning it is true that the end of the text string in $1 ends in .pet

    in this test, if we receive anything other that a 0, a true condition, it is true that the text string in $1 doesn't end with .pet and the 'then' portion of the if statements execute

    if we get through the sanity checks, we start processing
fn=`basename $1 .pet`
  • in this scenario, our argument $1 is medit-0.9.2.pet

    the basename $1 .pet command strips out the .pet extension

    the backticks ` ` are used to fill the variable with data

    the contents of $fn are : medit-0.9.2

    later we make a file called medit-0.9.2.txt
outdir="/root/doc"
  • earlier we decided to keep the course's document files in /root/doc, we define our destination directory as /root/doc

    The makelist function, explanations

    When the last command in var finishes, it returns to main to see if there are more commands, there are, main says: makelist
<${fn}.pet gzip --decompress | tar --list \
  • <${fn}.pet says to (re)direct contents of the file to the right
    We are not piping, we are redirecting to the external file gzip it's command to decompress the file

    (a pet file is a tar.gz file)

    Things generally come apart in the reverse order they went together.

    It went together like this: first the tar, second the gzip.

    To take it apart, first the gzip, then the tar.

    We pipe the gzip decompression to tar, we tell tar to list the contents, meaning the file names and directory names.

    Our \ character simply says, the next line is part of the command
| tee ${outdir}/${fn}.txt
  • We pipe to tee. tee sends the output to two different places. (1) the screen and (2) the specified file.

    This is the last command in the function makelist. The programming flow then goes back to main for its next instruction. There is not one and our program terminates.
~~~~~~~~~

Note on passing variables. We passed arg 1 to main. main passed it to var. We didn't pass arg 1 to makelist. We didn't need to because we used the fn variable which is available to our functions without a need to pass it to the functions, (after fn as been defined).

The result of running the command listpetfiles medit-0.9.2.pet is we have a complete record of all the changes made when we manually installed medit-0.9.2.pet in a text file called /root/doc/medit-0.9.2.txt

This record can be used if we want manually uninstall it.

More importantly, this is (hopefully) a good exercise in learning more about shell scripting.

Chapter assignment - as you please - script is attached

~

Chapter 36 - listing files contained in a pet archive
Attachments
listpetfiles.zip
shell script : listpetfiles
(502 Bytes) Downloaded 1870 times

Bruce B

#36 Post by Bruce B »

Chapter 37 - Test your learning

Barry K wrote a very useful script called probepart, this is a utility all 'command line' Puppians should know about.

Also you want to know about a companion script probedisk

Usage:

probepart
probepart -m (for listing in megabytes)

Exercise:

Run probepart and see what it does

Open the probepart script and read it, it's well written and well commented. It's not too short and not too long. About 100 lines including comments and blanks. You won't be able to understand it completely, so don't expect yourself to.

Just see how much of it you do understand and the command portions you recognize, based on what you've learned so far.

Hint:

which probepart to locate the file

double click the which output, to select and copy to a clipboard

$guieditor (paste)

Note: in open source programming, we often share our work in a community with other programmers. Among other things 'commenting' is very important. We can often see what another programmer does, but without comments, we may not know why.

~

Chapter 37 - Test your learning

Bruce B

Commenting your scripts

#37 Post by Bruce B »

Chapter 38 - commenting your scripts

In this chapter we will make a script to mount an iso file. The emphasis here is commenting. I will over do the commenting beyond what most programmers would do. One reason I've not been commenting our scripts is because in the forum posting using the code function, I preserve the formatting but I can't control color. In this post we forsake the important indentation for the purpose of commenting. The comments are in gray and the commands are in green.

#!/bin/bash

# function main

main() {

# list of main's commands

var "$1"
mountiso "$1"
displayfile
umountiso

}

# function var

var() {

# check for arg1, if not, display message and exit

[ ! $1 ] && echo "Argument missing, exiting" && exit

# if arg1 is not a file name, show message and exit

[ ! -f $1 ] && echo "$1 doesn't exist" && exit

# get an available loop device

lodev=`losetup-FULL -f`

# check if an available loop device was found, by using exit code
# from grep, hide output, then check exit code

echo $lodev | grep /dev/loop >/dev/null
[ "$?" != "0" ] && echo "Problem finding available loop device" && exit

# define our mount point in a variable

mntpnt="/mnt/iso"

# does our mount point exist?
# if not make it

[ ! -d $mntpnt ] && mkdir $mntpnt

# last command in function, automatically returns to main for next command

}

# function mountiso

mountiso() {

# setup the iso file on the loop device

losetup-FULL $lodev "$1"

# mount the iso file

mount-FULL -t iso9660 -o ro $lodev $mntpnt

# function umountiso

umountiso() {

# this function occurs when mc closes, when mc closes
# mc returns to the directory it was opened from

# unmount the iso file

umount-FULL $mntpnt

# free the loop device

losetup -d $lodev

}

# function display file

displayfile() {

# using midnight commander
# code execution halts until mc is closed

mc $mntpnt

}

# call to main and pass $1 to main

main "$1"

This is far more detailed commenting than you are likely to use or encounter. But if code were commented as well as this, it would be a 'piece of cake' for the next programmer to pick it up and work with it.

I've attached the script to the post, including comments and indents. Please download it and open it with geany or medit. Either of these editors highlight syntax and you will see how easy it is to read the bash script with an editor of this type.

If you have a iso file to mount, run the script

mtiso <filename>

~

Chapter 38 - Commenting your scripts
Attachments
mtiso.zip
script mtiso
(829 Bytes) Downloaded 1891 times

Bruce B

#38 Post by Bruce B »

Chapter 39 - mtsfs

In Chapter 38 we made a well commented script for easily mounting, viewing, working with and unmounting .iso files

The assignment for this chapter is:

Test mtiso and satisfy yourself it is a good script, if satisfied, use it as the template for making another script designed for mounting squashfs filesystems.

bin ( cd /root/bin )
cp mtiso mtsfs
$guieditor mtsfs &


make the necessary changes to the new file mtsfs

hint: the -t (type) parameter for an iso file is iso9660

the -t parameter for a .sfs archive is squashfs

~

Chapter 39 - mtsfs

Bruce B

Conditional expressions for integers

#39 Post by Bruce B »

Chapter 40 - Conditional expressions for integers

A lot of programming is about checking conditions. If this condition, we do this. It that condition we will do that. Or else we will do something different.

I think it's dawned on you by now, often times a programming routine simply makes a true or false check, as the basis for the decision what to do next.

Here I will introduce some basic bash math comparison operators

Code: Select all

[ "$1" -gt "$2" ] && echo "$1 is greater than $2"
[ "$1" -lt "$2" ] && echo "$1 is less than $2"
[ "$1" -eq "$2" ] && echo "$1 equals $2"
[ "$1" -ne "$2" ] && echo "$1 does not equal $2"
[ "$1" -ge "$2" ] && echo "$1 is greater than or equal to $2"
[ "$1" -le "$2" ] && echo "$1 is less than or equal to $2"
The 'echo' pretty much says what the operator does. In this routine we can have more than one true or false condition, because it runs from top to bottom, without branching.

For now, just remember this phrase, 'condition checks and branching'

bash knows what you entered as command line arguments. It also knows how many arguments you entered. $# is the number of arguments.

Before running the tests we could make sure sufficient number of arguments were entered, which would be two arguments

Code: Select all

[ "$#" -lt "2" ] && echo "insufficient number of arguments" && exit
Once again the true/false test. If it is true there are -lt ( less than ) two arguments, the commands execute, printing a message on screen and exiting the program

Our program only works on integers. We could make a filter to catch most times a user didn't enter an integer, like this:

Code: Select all

echo $1 $2 | grep [abcdefghijklmnopqrstuvwxyzAB\
CDEFGHIJKLMNOPQRSTUVWXYZ~!@_]>/dev/null \
&& echo "You must use integers" && exit
This sanity check is partial, it doesn't check for every wrong character. The reason why is some characters have special meaning and are hard to grep. So we will just do a little bit of sanity checking.

Putting our snippets in a logical order:

Code: Select all

[ "$#" -lt "2" ] && echo "insufficient number of arguments" && exit
echo $1 $2 | grep [abcdefghijklmnopqrstuvwxyzAB\
CDEFGHIJKLMNOPQRSTUVWXYZ~!@_]>/dev/null \
&& echo "You must use integers" && exit
[ "$1" -gt "$2" ] && echo "$1 is greater than $2"
[ "$1" -lt "$2" ] && echo "$1 is less than $2"
[ "$1" -eq "$2" ] && echo "$1 equals $2"
[ "$1" -ne "$2" ] && echo "$1 does not equal $2"
[ "$1" -ge "$2" ] && echo "$1 is greater than or equal to $2"
[ "$1" -le "$2" ] && echo "$1 is less than or equal to $2"
The exercise for this chapter is copy and paste the code. You can use newsh or fun. It doesn't matter.

You must be mindful of one thing. The two \ at the eol, must NOT have any white space to their right.

Hint: I've found keeping exercises is very helpful for reference. Suppose you forget an operator used in this session and you also forget the filename. But you can remember a phrase.

bin
grep "is greater" *


This command will show you every instance of 'is greater' along with the filename in your current directory. With the power of grep, you effectually have a catalog of your work.

~

Chapter 40 - Conditional expressions for integers

Bruce B

#40 Post by Bruce B »

Chapter 43 - some common Linux compression utilities

bzip2
gzip
zip


I'm attaching a less common compression utility in this post, called lzma, you probably don't have it. I compressed it as a bzip2 file.

Download it, to unpack it;

Midnight Commander, this time use the menu F2 to, practice learning how it toggles compression and decompression on a bzip2 file

Destination is /root/bin

For a matter of interest: In most cases bzip2 compresses tighter than gzip.

I've found the Linux zip compresses about the same as gzip - but zip doesn't delete the target after compression.

lzma compresses tighter than any of the three aforementioned. So I want you to have lzma. And you will need it for the next chapter.

~

Chapter 43 - some common Linux compression utilities

Post Reply