The Text-User Interface

Using applications, configuring, problems
Message
Author
Bruce B

#61 Post by Bruce B »

Chapter 63 - auto ext2|3 filesystem check and repair

The scripts in this post will automatically find, check and repair as needed your unmounted ext2 and ext3 partitions.

Script: autofsck

Code: Select all

#!/bin/bash

main()
{

    variables
    partition_types

}

variables()
{

    partitions=`fdisk -l | grep "83  Linux" | cut -d " " -f 1 | tr "\n" " "`

}


partition_types()
{

    for i in $partitions ; do
        guess_fstype $i | grep ext[23]>/dev/null
        if [ x$? = x0 ] ; then
        </proc/mounts grep $i>/dev/null
            if [ x$? != x0 ] ; then
                echo -en "\\033[1;36m""Checking $i"
                echo -e "\\033[1;36m"
                e2fsck -y $i
            fi
        fi
    done


}

main
Script: autofsck4rclocal

Code: Select all

## BEGIN AUTO EXT2|3 FSCK
partitions=`fdisk -l | grep "83  Linux" \
| cut -d " " -f 1 | tr "\n" " "`
for i in $partitions ; do
  guess_fstype $i | grep ext[23]>/dev/null
  if [ x$? = x0 ] ; then
    </proc/mounts grep $i>/dev/null
    if [ x$? != x0 ] ; then
      echo -en "\\033[1;36m""Checking $i">/dev/console
      echo -e "\\033[1;36m">/dev/console
      e2fsck -y $i >/dev/console
    fi
  fi
done
## END AUTO EXT2|3 FSCK
What you do with these scripts is up to you. In previous chapters, I explained portions of the programming logic which constitutes the scripts.
  • 1) find 83 Linux partitions
    2) filter out the ext2 and ext3
    3) see if they are unmounted
    4) if so do a file system check
    5) provide on screen feedback
Note: the one for /etc/rc.local directs output to /dev/console. rc.local is not running on a controlling tty, so we need to tell it put standard out to /dev/console

Some people think it takes too long to check the file systems each boot. Some people think it is unnecessary. Some people never check anything at all.

With ext3 partitions it takes me about 1/2 second to do the filesystem check. Your ext2 and ext3 partitions keep count of days between full checks and number of mounts between full checks.

A full check is typically about every 26 mounts, the full check is time consuming, no doubt.

(If you are like me, you are the system administrator - that's how it is)

Between these two scripts, depending on which script you use, you have the ability to run them as you please, or each boot, or never at all.

If nothing else, please read the two scripts, they are almost identical, except in style. See what style you like the best, try and understand each line.

~

Chapter 63 - auto ext2|3 filesystem check and repair
Attachments
autofsck.zip
(825 Bytes) Downloaded 1144 times

Bruce B

#62 Post by Bruce B »

Chapter 64 - the important filesystem checks

The pup_save file. That's where your operating system is, (for frugal users). It's the file you really want to keep free of errors. It's also the file most susceptible to errors.

A primary obstacle is; we can only safely check and repair filesystems when they are not mounted. The pup_save file gets mounted early in the boot process.

Moreover, over the last several releases, Barry has implemented various techniques for dealing with this. Considering the changes, I can't come up with a one solution.

Version 4.00 did the e2fsck automatically, people complained it was taking too long.

On newer versions, I've noted a variable which can be set puppy pfix=fsck

From the way I read the forum, most people are probably using a version with this variable. From that standpoint, maybe there isn't even a problem to solve.

I have no desire or intention of running Puppy or any Linux on filesystems with errors, so, if I were the admin over Puppy computers, I'd put the pfix=fsck line in GRUB.

The other partition of importance is the pup_save host partition. I modified my init to remove all checking of the pup_save file and set it to check the host and the pup_save file before anything of consequence occurs. Code excerpt to follow:

Code: Select all

mount -t proc none /proc
mount -t sysfs none /sys
mount -t rootfs -o remount,rw rootfs /
ln -s /proc/mounts /etc/mtab #resize2fs,e2fsck need this.
fsck_func() {
 echo -en "\\033[1;35m" >/dev/console #35=purple
    echo "filesystem check host please wait"
 /bin/e2fsck -y /dev/$PDEV1 >/dev/console
 /bin/mount -t ext3 /dev/$PDEV1 /mnt/data
 echo -en "\\033[1;35m" >/dev/console #35=purple
    echo "filesystem check pup_save.3fs"
 /bin/e2fsck -y /mnt/data/$PSUBDIR/pup_save.3fs >/dev/console
 /bin/umount /mnt/data
}
fsck_func
The host gets checked, the pup_save gets checked and note: it isn't even an ext2 format.

I won't explain anything concerning the above code, because of so many modifications elsewhere, and how they all fit together.

Point here is if an open source system isn't doing as you want it to, there is usually something, often a lot you can do to it.

You get the idea - man over machine - and it's a lot of fun.

~

Chapter 64 - the important filesystem checks

Bruce B

#63 Post by Bruce B »

Chapter 65 - assuring only one instance is running

I prepare these posts with Puppy's excellent outliner 'notecase'. Notecase allows multiple instances of itself. It also allows multiple instances of the same file.

To make things easy, I have a shell script called tui to open notecase with tui.ncd also loaded. Problem is notecase can open more than one tui.ncd and I can damage a document by editing a document open elsewhere.

I wish to demonstrate in this chapter how we can be assured we only have one instance of file open, using conditional checking and branching.

Remember how we can uses grep's exit code to verify conditions? We'll do it again here.

Code: Select all

#!/bin/bash
ps | grep -v grep | grep tui.ncd >/dev/null
if [ x$? = x0 ] ; then
	echo " notecase tui.ncd is already running, exiting . . ."
else
	notecase /root/Desktop/tui.ncd &
fi
Was that easy?

Notes:

/dev/null
is a mysterious black hole where things disappear forever and ever. You've see me use it before, now you know why, I don't want to see the output.

grep -v grep is saying: do not show any lines containing grep. problem is ps shows all processes, when we ran 'grep tui.ncd', which is a match, it became a process and we need filter it out with the -v switch. now we won't have a false positive.

The last argument in our pipe chain is the exit code which will be used. If 0, then tui.ncd is already running, (a true condition) we print a message and the shell having nothing else to do exits at the end.

else is a false condition, but that's not why it executes commands. It runs commands because nothing else did, (if that were the case).

If else runs, we start notecase tui.ncd with the & key to put it in the background so we can have our prompt back.

Assignment - Nothing to do with this code except understand it - if you want, modify it and come up with something useful for you.

~

Chapter 65 - assuring only one instance is running
Last edited by Bruce B on Fri 24 Jul 2009, 07:07, edited 1 time in total.

Bruce B

#64 Post by Bruce B »

Chapter 66 acd (means auto change directories)

The code in this chapter is unique, you might have to pay very careful attention.

First

I want you to be able to easily open .bashrc, edit it and source it. Here is the command I want you to copy and paste:

alias ea='mp /root/.bashrc ; source /root/.bashrc'


Notes: if you don't like mp, use another editor. Also, when using spaces in your .bashrc file always use ' after the = and ' at the end of line.

ea means 'edit alias'

Second

Copy and paste this command to .bashrc;

alias rf='source /root/.bashrc'

This will easily re-source an existing instance of bash. Suppose you have five instances open and change one. The other four need sourced again.

Third

Remember, we can change directories with aliases. I can type usrbin faster and easier than I can type cd /usr/bin.

I now give you a script which will add change directory aliases from the command line, without the need to open .bashrc and edit it. I call the script acd for auto change directories

To use, simply type acd + the name of the shortcut you want- when you are in the directory you want to add a shortcut to.

Example: when in /root/.mozilla, you can type acd .mozilla and your shortcut is added. You no longer need to type cd /root/.mozilla. Just type .mozilla Then use 'rf' to activate it in the current shell. Otherwise, it will activate next time you open it.

Forth

Using colors: I gave you colors to work with, this is the first script where I added colors. If you didn't install colors, then you must change the cecho to echo. If the colors are not to your liking you need to modify them

Lastly, here is the script;

Code: Select all

#!/bin/bash
main() {

    variables $1
    check_dupes $1
    make_alias $1

}

variables() {

    $clr
    file=/root/.bashrc
    [ ! $1 ] && cecho red " missing argument" && exit
    name=$1
    dir=`pwd`
    tmpfile=/dev/shm/bashrc

}

check_dupes() {

    cecho white
    < $file grep "alias $1=" 
    if [ "$?" = "0" ] ; then
        cecho yellow "alias name \"$1\" already exists"
        cecho white "replace it (y,n)"
        color black
        read -n 1 a
        if [ "$a" = "y" ] ; then
            color white
            < $file grep -v $name>$tmpfile
            cp $tmpfile $file
            return
        else
            echo    
        fi
    exit
    fi

}

make_alias() {

    cecho white "alias $1='cd $dir'" n
    cecho white " "
    cecho green "added to list"
    echo "alias $1='cd $dir'" >> $file

}

main $1
Assignment - this file very useful, but optional. Please use attached file rather than the pasted code. Enjoy

~

Chapter 66 acd (means auto change directories)
Attachments
acd.zip
(531 Bytes) Downloaded 1135 times

Bruce B

#65 Post by Bruce B »

Chapter 67 - easy note taking

As a part of our computing tasks, we often want to jot down a few notes. With the GUI, this might involve opening a text editor, making our notes, saving changes and closing.

This task can be made much easier with a simple script, considering command line users often have the emulator open at all times.

For purpose of this chapter we will call our script note.

Code: Select all

#!/bin/bash
cat >> /root/my-documents/note.txt
That's an easy enough script. When done jotting the notes, hit ctrl+d to close note and save your changes.

Like many, if not most scripts, they can be enhanced with features added, we'll do it.

Some scripts we plan to distribute, they need to have maximum portability. As a rule, we want all our scripts to be as portable as is reasonably possible. But for ourselves we might do non conventional things to make them easier.

In this case, if I type note and any character it brings up a menu. For example:
  • note a
    note -
    note note
    note (with no argument works normally)
Here is the enhanced note taking script, comments below.

Code: Select all

#!/bin/bash

main() {

      variables
      [ "$1" != "" ] && give_menu
      case_answer

}

variables() {

    $clr
    fn="/root/my-documents/note.txt"
    answer="/tmp/noteoptions.tmp"
    [ -f $answer ] && rm $answer

}

case_answer() {

    take_notes() {

        cecho black "Ctrl + D to finish"
        cecho green
        cat >> $fn
        clear
        exit

    }

    [ ! -f $answer ] && take_notes
    ans=`cat $answer`

    case $ans in

        x) clear ; exit ;;
        c) clear ; cecho black ; cat >> $fn ; clear ;;
        d) dialog --title "$fn" --textbox $fn 22 70 ; clear ;;
        e) mp $fn ; clear ;;
        s) ispell $fn ; clear ;;
        *) clear ; exit ;;
        
    esac

    [ -f $answer ] && rm $answer

}

give_menu() {

    dialog --backtitle "Note Menu" \
    --nocancel --menu "Options for note.txt" 0 30 5 \
    "x" "exit" \
    "c" "cli low contrast" \
    "d" "display file" \
    "e" "edit in mp" \
    "s" "spell check" \
    2>/tmp/noteoptions.tmp

}

main $1
Comments

As per style all control is in main.

We've seen examples of nesting loop and if statements. Here we see an example of nesting a function.

Reinforcement: Bash reads from top to bottom. We must read the function before calling it. This is why main is at the bottom and in the case of the nested function, it is read before called.

Sometimes we want to take notes without giving someone an opportunity to read over our shoulder. I included functionality to lower contrast. My background is black so I used black. If you want to use this script, you may need to modify these colors according to your background.

If you didn't install cecho, well, modify the script accordingly.

Typically our terminal is black with a light gray text. With Puppy it might be a white bg with a black fg.

I like colors for their own sake. Also, I think colors can give a nice finished look to our scripts.

In this script I've used 'dialog' for some of the options. But, I haven't taught dialog yet. I would like to emphasize dialog is not a graphics program. Everything you are looking at in dialog is text.

See how you like the command line note utility, what you can learn or do with it.

~

Chapter 67 - easy note taking

(don't copy and paste, use the attachment)
Attachments
note.zip
(582 Bytes) Downloaded 1099 times

Bruce B

#66 Post by Bruce B »

Chapter 68 - (ComeOn Dialog!)

I suppose any shell programmer will want to know 'dialog'. I've used it a couple times, in this series. This is your first lesson on dialog. We'll be using its 'menu' feature in this chapter. Here is the code:

Code: Select all

#!/bin/bash

main() {

    variables
    options
    caseselection
    exec $0
    
}

variables() {

    tmpfile="/tmp/dialogdemo.tmp"
    [ -f $tmpfile ] && rm $tmpfile

}

options() {

    dialog --backtitle "Dialog Menu Example" \
    --nocancel --menu "Please choose" 0 35 5 \
    "x" "eXit" \
    "1" "abiword word processor" \
    "2" "geany programmer's editor" \
    "3" "gFTP" \
    "4" "leafpad editor" \
    2>/tmp/dialogdemo.tmp    

}

caseselection() {

    opt=`cat $tmpfile`

    case $opt in
        1) cd /root/my-documents ; abiword & ;;
        2) geany & ;;
        3) gftp & ;;
        4) leafpad & ;;
        x) clear ; exit ;;
        *) clear ; exit ;;

    esac

}

main
Notes

In the function caseselection 1) we use ; as a command separater, the ;; in the case statement signals the end

* in the case statement says, if the wrong key was pressed, clear screen and exit

In options note all the \ , these several lines would be one long line without the \ s.

2>/tmp/dialogdemo.tmp redirects our choice to that file for later use in the case statement

--nocancel --menu "Please choose" 0 35 5
  • 0 is height by leaving it at 0, dialog will choose the height

    35 is our defined width

    5 is the number of items in our list

    --nocancel means don't display the cancel button

    --menu means we want dialog to make a menu

    "Please choose" is the menu title
In main the 'exec $0' has the script restart each time, unless the user exits.

~

Optional Assignment: make a copy of this file, change it, work with it until you feel you have fair command of this basic menu system.

The script is mainly useful as a demo. But I recommend storing it someplace for quick reference later when you make a more useful menu.

~

Chapter 68 - (ComeOn Dialog!)
Attachments
dialog-menu.zip
(509 Bytes) Downloaded 1067 times

Bruce B

#67 Post by Bruce B »

Chapter 69 - awk

I use awk in my scripts for printing and rearranging specified columns.

Suppose I want to keep an up to date hosts file to save the time of the DNS queries.

The utility host makes these DNS queries, but formats them wrong for use in the hosts file

host -4 example.com
prints;
example.com has address 208.77.188.166
the above formatted output won't work with the /etc/hosts file

host -4 example.com | awk '{ print $4" "$1 }'
prints;
208.77.188.166 example.com
this output is perfect for /etc/hosts

What I did to format it right was print column 4 first, then a space character, followed by column 1.

Keep in mind, awk is much more powerful than my simple example. (and potentially much more complex)

For some chapters on awk

Linux Shell Scripting Tutorial (LSST) v1.05r3
A Beginner's handbook - by Vivek G. Gite
http://www.freeos.com/guides/lsst/index.html

I've attached the file host, which isn't included in Puppy, so you can make your own DNS queries and test the lines in this chapter. Put it in your /root/bin directory. Don't confuse the name with hosts, they are two different files.

~

Chapter 69 - awk

Bruce B

#68 Post by Bruce B »

Chapter 70 - piping to scripts

I'll call this script ucase

#!/bin/bash
tr [:lower:] [:upper:]
exit 0


I leave it to you to figure how to make lcase

This is the first time we've used an exit code in a script.

We've seen many examples of piping to binary files. This is the first time we've made a script for piping.

My main point is to demonstrate we can pipe to our scripts, if we build them for that purpose. And considering we might want a successful return code we add one.

It would be easier to say:

< infile ucase


than

< infile tr [:lower:] [:upper:]


But frankly, I think ucase and lcase are too seldom used to even bother with. However, I think it good to know about the utilities in your tool box. With tr, if we want to change case in our files or even filenames, it's fairly easy.

~

Chapter 70 - piping to scripts

Bruce B

#69 Post by Bruce B »

Chapter 71 - updating dialog

My main purpose in this chapter is to make an exercise where you can practice updating an application if it needs updated. In other words: practice developing skills

While visiting the Dialog Web Site, I noticed my Puppy version of dialog was old. So I updated it.

To check your dialog version:

dialog --version
Version: 1.1-20080819 (my current one)

If yours is older and you want to accept the assignment of updating it, you can go to the Dialog home page, linked above. Then to the 'download the latest section'. The file you would want would be dialog_1.1-20080819-1_i386.deb

I think your training level should be such that you can install this Debian package using 'disrpm' and 'mc' without much explanation.

Listed below are the package contents, note; they all go in /usr. You may choose not to install foriegn locales.

Please note: Lots of documentation to reference and learn from. And you can place documentation in different directories or make convenient symlinks.

Code: Select all

|-- control  <- DON'T INCLUDE
|-- md5sums  <- DON'T INCLUDE
`-- usr
    |-- bin
    |   `-- dialog
    |-- include
    |   |-- dialog.h
    |   |-- dlg_colors.h
    |   |-- dlg_config.h
    |   `-- dlg_keys.h
    |-- lib
    |   |-- libdialog.a
    |   `-- perl5
    |       `-- dialog.pl
    `-- share
        |-- doc
        |   `-- dialog
        |       |-- CHANGES.gz
        |       |-- README
        |       |-- changelog.Debian.gz
        |       |-- changelog.gz -> CHANGES.gz
        |       |-- copyright
        |       `-- examples
        |           |-- calendar
        |           |-- calendar-stdout
        |           |-- calendar2
        |           |-- calendar2-stdout
        |           |-- checklist
        |           |-- checklist-utf8
        |           |-- checklist10
        |           |-- dselect
        |           |-- editbox
        |           |-- editbox-utf8
        |           |-- editbox2
        |           |-- form1
        |           |-- form2
        |           |-- fselect
        |           |-- fselect-stdout
        |           |-- fselect1
        |           |-- fselect1-stdout
        |           |-- fselect2
        |           |-- fselect2-stdout
        |           |-- gauge
        |           |-- gauge0-input-fd
        |           |-- gauge2
        |           |-- gauge3
        |           |-- infobox
        |           |-- infobox2
        |           |-- infobox3
        |           |-- infobox4
        |           |-- inputbox
        |           |-- inputbox1
        |           |-- inputbox2
        |           |-- inputbox3
        |           |-- inputbox4
        |           |-- inputbox5
        |           |-- inputbox6-utf8
        |           |-- inputbox7
        |           |-- inputmenu-stdout
        |           |-- inputmenu1
        |           |-- inputmenu2
        |           |-- inputmenu3
        |           |-- inputmenu4
        |           |-- menubox
        |           |-- menubox-utf8
        |           |-- menubox1
        |           |-- menubox10
        |           |-- menubox2
        |           |-- menubox3
        |           |-- menubox4
        |           |-- menubox5
        |           |-- mixedform
        |           |-- mixedform2
        |           |-- mixedgauge
        |           |-- msgbox
        |           |-- msgbox1
        |           |-- msgbox2
        |           |-- msgbox4-eucjp
        |           |-- msgbox4-utf8
        |           |-- password
        |           |-- password1
        |           |-- password2
        |           |-- pause
        |           |-- radiolist
        |           |-- radiolist10
        |           |-- textbox
        |           |-- textbox2
        |           |-- timebox
        |           |-- timebox-stdout
        |           |-- timebox2
        |           |-- timebox2-stdout
        |           |-- yesno
        |           |-- yesno2
        |           `-- yesno3
        |-- locale
        |   |-- ar
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- be@latin
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- bg
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- ca
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- cs
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- cy
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- da
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- de
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- el
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- eo
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- es
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- et
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- eu
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- fi
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- fr
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- ga
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- gl
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- hi
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- hr
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- hu
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- id
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- it
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- ja
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- ku
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- lt
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- mg
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- mk
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- ms
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- nb
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- nl
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- pl
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- pt
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- pt_BR
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- rm
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- ro
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- ru
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- rw
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- sq
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- sr
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- sv
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- th
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- tr
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- uk
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- vi
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- wa
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   |-- zh_CN
        |   |   `-- LC_MESSAGES
        |   |       `-- dialog.mo
        |   `-- zh_TW
        |       `-- LC_MESSAGES
        |           `-- dialog.mo
        `-- man
            |-- man1
            |   `-- dialog.1.gz
            `-- man3
                `-- dialog.3.gz

107 directories, 134 files
~

Chapter 71 - updating dialog

Bruce B

#70 Post by Bruce B »

Chapter 72 - symlinks

If you did the exercise in Chapter 71, you now have many examples of how to use dialog.

These examples are in;
(file://)/usr/share/doc/dialog/examples

Note: when we have a directory 5 levels deep, we want easy ways to access that directory, if we plan to visit it often.

1) You could bookmark this directory in Midnight Commander; merely navigate to /usr/share/doc/dialog/examples, then ctrl / to add the bookmark

2) you could add an alias

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

This chapter looks like a good place to discuss the ln command.

Suppose we want to access /usr/share/doc/dialog/examples as if it were a subdirectory in our doc directory /root/doc; here is how;

cd /root/doc
ln -s /usr/share/doc/dialog/examples


This will make what we call a 'symlink' called examples which points to /usr/share/doc/dialog/examples and acts as if we directly accessed /usr/share/doc/dialog/examples

Suppose we don't want the name examples because it is too ambiguous, and it is. Then a different command;

cd /root/doc
ln -s /usr/share/doc/dialog/examples dialog-examples


Says we want our symlink named - dialog-examples

(we choose the name)

~

Chapter 72 - symlinks

Bruce B

#71 Post by Bruce B »

Chapter 73 - the dot

A chapter on the character period (.). Also known in the slang as the dot. (well, yes)

In many cases the punctuation character - period - has a variety of meanings. I won't say anything about the dot as a punctuation character because we all know it as such.

The dot as the current directory

rox . (opens rox in the current directory)
mc . (opens mc in the current directory)

./scriptname (runs the script in the current directory, even though it is not in the path)

Dot as the source command shorthand

. filename (is shorthand for the long command source)
source filename (being the same as the command above)

Utilities


find /usr | grep ".png" finds all files with the text string 'png' even if there is no dot

find /usr/bin | grep "\.png" finds all files with only the text string '.png'

Directories

Whereas . means the current directory, .. would mean the parent directory.

cd .. would take you back (up) one directory

cd ../.. would take up back (up) two directories

cd ../foo would take you back one and over to foo

Guess what rox .. , or mc .. would do?

Dot for hiding files

When a file name starts with a dot, such as .foo, it's called a hidden file. It is not really a hidden file, but it won't be displayed by many programs.

If you want to open the bookmarks file in /root/.mozilla/somewhere/ it might not show in leafpad. Worse, files in this directory might not show to Mozilla (SeaMonkey)

A SeaMonkey workaround could be a symlink

cd
ln -s .mozilla mozilla


Then you could access /root/.mozilla by way of /root/mozilla.

cp and mv commands

These require a source and destination. Again the dot applies as the current directory.

Example:

cp /root/foo .

The dot suffices as the destination and you don't need to type in the directory. cp understands . to mean the current directory

This is all for the chapter. If you find the punctuation mark 'period' is behaving differently that a mere printing character, it might be because it really is.

~

Chapter 73 - the dot
Last edited by Bruce B on Fri 31 Jul 2009, 12:35, edited 2 times in total.

Bruce B

#72 Post by Bruce B »

Chapter 74 - how to not auto start X

I've seen this question asked with some frequency. I'll show you how I boot to the command prompt without starting X

I edit /etc/profile and change the line below

from
exec xwin
to
# exec xwin

When using a Linux that uses run levels, I edit /etc/inittab to use run level 2 or 3

~

Chapter 74 - how to not auto start X

Bruce B

#73 Post by Bruce B »

Chapter 75 - a colorful calendar

Puppy comes with an useful utility called cal. I won't say much about it except, familiarize yourself with it.

I'm attaching to this post a similar utility which has been around for ages called ccal. Apart from displaying a colored calendar, it has the ability to keep appointments, birthdays, dates and other items for you.

I'm working and have about completed a script to make data entry for this utility very easy. A day or three maybe?

This is version 3.5 and I think a slightly newer version is available from at least the Debian repositories. But in reading the release notes, I didn't see a particular advantage to it.

Enjoy!

~

Chapter 75 - a colorful calendar
Attachments
ccal.zip
(11.61 KiB) Downloaded 1057 times

Bruce B

#74 Post by Bruce B »

Chapter 76 - conditional checks and branches

Writing programs for yourself is different than writing for distribution. You already know many of the conditions on your computer. You don't necessarily know all you need to know on your client's computer. For this reason, you may want to check some conditions prior to running the meat of your script. This of course especially applies if damage can be done.

Example 1 - do we have all dependent files?

Sometimes the successful operation of our script requires other files. Here is an example of how to check for dependent files:

Code: Select all

for i in which man2html foobar
do
	file=`which $i`
	if [ x$file = x ] ; then
		echo $i missing
		missing=1
	fi
done

[ x$missing = x1 ] && exit 1
Explanation
  • for loop with three arguments: which, man2html, foobar

    which reports the location of a file, if found

    if the variable file is empty we display problem on screen and set missing=1

    test for missing=1, if true, exit

    we didn't find the file 'foobar' and we branch to exit the script with an exit code of 1 which we may or may not need or even want.
Example 2 - is a process running?

Code: Select all

XRUNS=`pidof X`
if [ x$XRUNS = x ] ; then
	echo "We'll edit file with Minimum Profit"
else
	echo "We'll edit file with Geany"
fi
We use a different text editor depending if X is running.

Also, an important command, pidof was just introduced! Let's learn more about this one.

Exercise:

ps


You'll see a long list of processes and one about like this:

12288 root 31932 S < X :0 -br -nolisten tcp

12288 is the pid (Process ID)

By the contents or lack of contents in the variable we made called XRUNS, our script can know if X is running. Based on this criteria, we can branch accordingly.

As you please: make copies of these scripts, work with them some, modify them until you feel you have all the command over the routines you need or want.

~

Chapter 76 - conditional checks and branches

Bruce B

#75 Post by Bruce B »

Chapter 77 - Links browser

For this chapter, I'd like you, if you are following the course, to download and install a curses browser. Ultimately, I think we'll have two or three browsers, but currently I'd like you to install 'links' from Puppy's official server.

links-2.1pre30.pet in the pet packages 4 directory ( there is an earlier version in the 3 directory, so make sure you get it from the 4 directory )

links differs from other ncurses browsers in that it also has a graphics mode which when running X can be enabled with the -g switch.

You could make a script called xlinks to save extra typing.

Code: Select all

#!/bin/bash
links -g "$@"
or make an alias

Code: Select all

alias xlinks='links -g'
To install it, download it with mc from ftp.ibiblio.org. After download, select file, hit enter key, navigate to usr/bin in the virtual file system and copy links to /root/bin. It's just a one file install.

Important! Then add a variable to /etc/profile.local

export PAGER=links

links can be used as a browser, local file viewer for web documents, man pages and text pages. And we have a couple upcoming scripts which will use links.

~

Chapter 77 - Links browser

Bruce B

#76 Post by Bruce B »

78 - select menu

I show a simple way to make a useful menu with bash. When we did the look utility, I used this bash' select command. I didn't however explain it at the time, thinking I'll do it later. Now is later.

In chapter 77 we installed 'links' and set the variable PAGER.

By now, I hope you have some documentation in our 'doc' directory /root/doc, because this script is for perusing the /root/doc directory.

I called this script doks, but as you know you can give it another name.

Code: Select all

#!/bin/bash
main() {

    vars
    menu

}

vars() {

    # $clr
    dir=/root/doc
    [ ! -d $dir ] && echo "$dir doesn't exist, exiting" && exit
    PS3='Please select : '

    # branch example, use different mode for the pager if X is running

    xrun=`pidof X`
    [ x$xrun != x ] && graphics="-g"

}

menu() {

    cd $dir
    clear ; echo -e \\n\\n\\n\\n\\n
    echo "Scripting And Linux Documentation" ; echo
    select fname in * ;
    do
           $PAGER $graphics ${dir}/${fname}
          break;
    done
    exec $0

}

main

# 2009-08-02
With this utility you can type in doks and easily read the files in this directory with your new pager. (if they are the right kind of files)

What I'd like for an assignment is to have you modify this file some, give it colors, change the color of PS3. Change and color the title, so on and so forth.

You can setup these simple little menu systems throughout your system as needs be. For example, I have scripts to run wine supported files. I type in 'winem', short for 'wine menu' and then select the number of the application I want to run.

The wine scripts have their own place in the PATH so I can run them directly also with command line arguments. And while on the subject, you can add lots of paths to grow your system and keep it organized.

A little change of subject, but while I'm thinking about it, when we installed mrxvt it didn't come with a complete rc file. I made a complete file, not all the values are entered, nor should they be, but the options are. With the rc file, it's easy to change the way mrxvt looks and behaves. And of course see the options available which the other file didn't show.

I'll attach it as mrxvtrc and you can download it to /root and use

swapf mrxvtrc .mrxvtrc

Would you like a utility for swapping directories? If so, you can use swapf as the template. Copy it to the name swapd and change it internally, accordingly.

~

78 - select menu
Attachments
mrxvtrc.zip
(1.8 KiB) Downloaded 2043 times

Bruce B

#77 Post by Bruce B »

Chapter 79 - Line endings

This chapter is important to understand, but I don't know under what circumstances you will need to apply the information.

Unix, MS-DOS, and Mac all use different line endings. Because of this we can end up with a Mac text file, a DOS text file or a Unix text file.

Also we can end up with a hodge podge of line endings if we've been editing with DOS and Linux editors, which don't convert all unchanged line endings on save.

Puppy and most Linux come with utilities called unix2dos and dos2unix, when you port text based documents from one operating systems, it's good to make your line endings consistent.

In order to help you better conceptualize I have hexdump for the three file types

Unix / Linux File - Line Feed (LF) (0x0a)

Code: Select all

74 68 69 73 20 69 73 20  61 20 75 6e 69 78 20 66  |this is a unix f|
69 6c 65 0a 69 74 20 75  73 65 73 20 6c 69 6e 65  |ile.it uses line|
20 66 65 65 64 73 0a 66  6f 72 20 6c 69 6e 65 20  | feeds.for line |
65 6e 64 69 6e 67 73 0a  6e 6f 74 65 20 74 68 65  |endings.note the|
20 30 61 0a 0a                                    | 0a..|
Messy DOS File - (Carriage Return + Line Feed) (CR+LF) (0x0d 0x0a)

7

Code: Select all

4 68 69 73 20 69 73 20  61 20 6d 65 73 73 79 20  |this is a messy |
64 6f 73 0d 0a 66 69 6c  65 2c 20 69 74 20 75 73  |dos..file, it us|
65 73 20 63 61 72 72 69  61 67 65 0d 0a 72 65 74  |es carriage..ret|
75 72 6e 73 20 61 6e 64  20 6c 69 6e 65 20 66 65  |urns and line fe|
65 64 73 0d 0a 66 6f 72  20 6c 69 6e 65 20 65 6e  |eds..for line en|
64 69 6e 67 73 2c 20 6e  6f 74 65 0d 0a 74 68 65  |dings, note..the|
20 30 64 20 61 6e 64 20  30 61 0d 0a              | 0d and 0a..|
Mac File - Carriage Return - 0x0d

Code: Select all

74 68 69 73 20 69 73 20  61 20 73 61 6d 70 6c 65  |this is a sample|
0d 6f 66 20 61 20 4d 61  63 20 66 69 6c 65 0d 6e  |.of a Mac file.n|
6f 74 65 20 74 68 65 20  30 64 2c 20 74 68 65 73  |ote the 0d, thes|
65 0d 61 72 65 20 63 61  72 72 69 61 67 65 20 72  |e.are carriage r|
65 74 72 75 6e 73 0d                              |etruns.|
I'm including a utility called 'tofrodos' with this post. One binary file and one text help file

You can also download the source and compile it yourself from:

http://www.thefreecountry.com/tofrodos/index.shtml

Puppy's equivalent utilities don't have the features tofrodos has, so that's why I'm adding it.

I have an idea it will convert Mac files, even if the help doesn't say so, or prepare them for conversion, with a little help from simple script. But I need to test this first.

The main things to remember from this chapter, I've highlighted in bold.

~

Chapter 79 - Line endings
Attachments
tofrodos.zip
(6.84 KiB) Downloaded 1982 times

Bruce B

#78 Post by Bruce B »

Chapter 80 - Clean File Improved

I removed notrail from Chapter 50 for a better utility posted in this chapter.

The contents of notrail are: one shell script called notrail, you will want to replace it with cleanf ( means clean file )

The main change is: I wrote a C program pipe which does more with the characters than the sed command.

Zip file contents are:

cleanf - the script to run
cleanf-bin - the script automatically runs this file
cleanf-bin.c - the source code distributed GNU version 2

That's about it for this chapter, enjoy!

~

Chapter 80 - Clean File Improved
Attachments
cleanf.zip
(2.27 KiB) Downloaded 1969 times

Bruce B

#79 Post by Bruce B »

Chapter 81 - How to do some modest binary hacking

Rule #1 is make a backup
Rule #2 is make a backup

The hex editor is the right tool for the job, unless you insert or delete bytes the byte size of the file doesn't change. The hex editor displays all content.

I compiled gqview and found out it wanted its help file from a subdirectory of my temporary build directory.

I edited the directory string in the file to point to the right place. It only took a minute and beat debugging the source code.

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

More recently, as in today, I was using a really neat PIM (Personal Information Manager)

It has (had) 1 pane for a todo list, 1 pane for the calendar and one pane for the appointment list.

Problem is I don't have many appointments. But I do have goals and the way the PIM is organized goals work perfectly in place of appointments. So I hacked it replacing this string
Appointments
with this
Goal Planner

These characters are only for display purposes and the number of characters I replaced was identical, so the file size didn't change, which you really likely don't want to do.

I've attached a little picture of the changes.

The idea I wish to convey in this chapter is don't be afraid to change some human readable text. ( you followed rule number #1 and #2 )

Generally, when you are inside the file, you can intuit if the text you plan to change is okay to change.

~

Chapter 81 - How to do some modest binary hacking
Attachments
hex-changes.png
(5.22 KiB) Downloaded 2786 times

Bruce B

#80 Post by Bruce B »

Chapter 82 - File extensions and file names

Sometimes we need to add and remove file name information. I'll show an example. Suppose we wanted to decode .mp3 to .wav files with lame.

Lame's syntax is like this lame -decode <infile> <outfile>

For 16 songs that would be a lot of typing. If we want to do a good job we want the outfile with a .wav extension and not a .mp3.wav extension.

Suppose our files are named like this Track_01.mp3, Track_02.mp3, . . .

We have an advantage from the start because we know the infile extension.

Puppy comes with an external utility called basename. Basename will strip the directory name from our file, if the directory name exists, but it won't strip the extension unless we tell it what it is.

Back to the old for loop.

Code: Select all

for i in *mp3 ; do
    fn=`basename .mp3`
    lame -decode ${fn}.mp3  ${fn}.wav
done
When the loop is done, we have 16 .mp3 and 16 .wav files and it didn't take typing. Note this would be a reusable script.

It wouldn't handle song names with spaces, but as the administrator of your Linux system, I think you are better off not introducing file or directory names with spaces.

The idea in this chapter is showing the utility basename and how to remove and change extensions. If you 'got' that much you got it. There are other ways to capture extensions and remove them. I'll save that for later.

~

Chapter 82 - File extensions and file names

Post Reply