Wednesday, March 4, 2015

Screen Dump


The other week J.K. at SFVlug was asking if I could provide some notes on the GNU 'screen' program. Here, extracted from some earlier notes, and beefed up with a few references I use, without further commentary, are the basic commands, hotkeys, and other data I need for most of my 'screen' use.




some screen notes:

Note: keep in mind screen can be run inside of xterm and other environments

to kill a range of screens:

for i in {3..13} ; do screen -p $i -X kill ; done

screen -h / --help     (of course)
there are or can be /etc/screenrc ~/.screenrc files
screen -ls    list screen sessions
screen -r    ####.tty##.        attach to detached screen
screen  -r -DD   violently try to grab or start a screen session
                   if none available  doing whatever it takes
ESC == ^A  normally (I usually redefine to ^O)
            Some people like ^@  (which results in ^ as ESC)
ESC-?  help 
ESC-d      detach (throw into background) current screen session
ESC-c      open another virtual console
ESC-k      kill the current virtual console (or you can just exit it)
ESC-t  show system info (including time/date by default)
ESC-:  open screen command prompt at bottom of console
               (can enter commands normally mapped to keys etc.)
                    ~ ':' ex-mode in vi or lynx, or w3m
ESC-p/n     previous / next virtual console, cycling through them
ESC-#       (#==0-9) select console  #
ESC-A       give virtual console a name (or view the current console name)
ESC-'       pull up prompt to give a virtual console # or name & then switch
ESC-"       pull up virtual console selection menu
ESC-[       put in copy / scroll mode
  in copy/scroll mode:
      ('.'   for  a register, is interpretted as the paste buffer )
      (~vi cursor movement)
      c / C   set left / right margins
       or  set a mark (first or second)
      W       grab word under cursor
      Y       mark whole line
      y       mark from start of line
      x       eXchange current cursor position and mark
      a       kick into append (to buffer) (instead of overwrite buffer ) mode
      A           "          *AND* set a mark
      J     cycle through join/join with spaces/join with commas/multiple lines
      |       move to absolute column       
      g       go to top of scroll buffer
  ESC-]      dump paste buffer to stdout
   
shared sessions with screen:
http://www.lowlevelmanager.com/search/label/pair%20programming
              (courtesey local Perl Mongers chief)
http://www.caikesouza.com/blog/category/linux/
(see article for permissions set up)

(for user foo:)
screen -S pairprog
^A :multiuser on
^A :acladd bar  

To make other read-only:
^A :aclchg bar -w "#"

(user bar:)
Then to join:
screen -x foo/pairprog

http://www.lafn.org/~aw585/gh.html
           - has some examples of setting up a text console 'desktop',
               and stuffing commands on startup into a program on startup
                 with screen

http://isthereanotherquestion.blogspot.com/2008/06/full-screen-ahead.html

some packages/programs to interact with screen (I don't use any of these):
iselect
screenie
byobu

Some similar programs:
tmux (~a ground up rewrite)
dvtm   (simpler, more tiling oriented)
splitvt   (very simple lite horizontal split)
fbterm    (requires frame buffer) 

-- Dallas E. Legan 2015 March 04

 

Saturday, September 20, 2014

Extracting the mp3 From a Video


(In reference to a recent SFVLUG meeting....)

At the last meeting the question of how to extract an audio already in mp3 format from a video into a stand alone file came up.

I suggested something along the lines of

$ ffmpeg -i videofile -ac copy audiofile.mp3

making sure the output file has an extension of '.mp3', which is almost right but has an error.

It should be:

$ ffmpeg -i videofile -acodec copy audiofile.mp3

I mentioned mkvextract if the file was already matroska in the conversation. This actually implies another method of doing this, first convert to matroska with mkvmerge, then use mkvextract to dump the audio track:

$ mkvmerge -o intermediate_video.mkv videofile

$ mkvextract tracks intermediate_video.mkv 1:audiofile.mp3



$ rm -f intermediate_video.mkv

assuming, as typically happens, that track 1 of the matroska is the audio file. That probably should be verified, with

$ mkvmerge --identify intermediate_video.mkv

Yet another approach would be


$ mplayer -dumpaudio -dumpfile audiofile.mp3 videofile

Apparently mpv, an mplayer fork, does not currently support '--dumpaudio'. (To my suprise.)

Sunday, November 24, 2013

Undocumented scp



Recently I had need to set up some ssh keys and restrict their use to
only work with scp, not ssh in general.

After some fumbling around, I conducted some tests with no restrictions on the key
at the target remote host, with verbosity maximized with the local invocation of scp.
Scanning the output, there was mention of running 'scp -v -t ...' on the remote
system, which provided the key on how to do this.
With a bit of further testing, I found placing

command="/usr/bin/scp -v -t .../target/directory/"

in the options of the key involved in the ~/.ssh/aurthorized_keys
produced the desired effect.

Thinking I was probably not the only person to notice this, I googled
for "scp undocumented" and found references to '-d' and '-f' keys as well.

In the task of restricting ssh keys to only scp functionality there
seemed to be what I percieved as a lot of murkiness, with references
to a special 'scponly' shell etc., where an understanding of the
'-f' and '-t' keys would seem to be good for a lot of mileage.
Introducing other programs seems to introduce the possibility for
more bugs and confusion.
There is some mention of the '-f' and '-t' switches in O'Reilly's
SSH book, but not the man page.
("SSH, The Secure Shell: The Definitive Guide",
ISBN: 0-596-00011-1
Daniel J. Barrett and Richard E. Silverman
chapter 3.8.1, first edition 2001)

After some experiments, these are the guidelines I found for using
the '-t' and '-f' switches with cp in ~/.ssh/authorized_keys command="..." options.


1) Locally, everything after the ':', the user@host#port command line description of the remote
host, or ~/.ssh/config defined host parameters, is ignored.
This means you must specify the target directory or
file name in the remote hosts 'command=' option.
This may seem inflexible, but that is actually the goal of 'command=' options, to
reduce flexibility, and restrict the key to only desired effects.
Unless explicit, fully qualified directory paths are used,
directories are relative the home directory of the receiving user account.

2) '-t' ("To:")seems to closely parrallel the '-t' option in Gnu implimentations of 'cp' and
'mv' commands, but with scp you use it only in the remote 'command=' option.
It is used when the remote host is to recieve files.
If a file name is specified after '-t', it will be used literaly, so patterns
in this name are useless - they will only result in awkward file names that
use file matching metacharacters.
This also means that if a file name is specified, it will be overwritten each time
scp using the key is used, unless other actions have been taken
between invocations. Example:

command="/usr/bin/scp -v -t some/dir/".......

3) '-f' ("From:") is used when the remote host is sending files.
A pattern for a file name must be
appended to the directory specification. This pattern can be an explicit, particular file name.
To copy and entire directory, you would use '*', so:

command="/usr/bin/scp -v -f some/dir/*".....

4) If the desired effect is to recursively send a directory tree,
the '-r' switch must be used at both ends of the network connection, the simple invocation of
scp, and the 'command=' forced command.
When the remote host is recursively sending the tree, some pattern matching files
and directories must be part of the path specified in the 'command=' option.
This would most likely be '*' (dir/path/*).
When the remote host is receiving a recursively send directory tree, no file name
can be included 'command=' option, or on metacharacter garbage will result.
If you are sending directory trees recursively, it is likely you really want to
use rsync, but there may be obscure uses for this feature of scp.

5) I've yet to determine anything about the '-d' switch.

Dallas Legan,
dallas.legan@gmail.com
2013 Nov. 24

Monday, April 23, 2012

Rebirth?

I'm taking a break from the series on PDF handling,
for a bit, while reviving my blog.
Originally, I was going to post to thank Google for re-enabling support for Lynx some time back.
I'd noticed being able to log in with Lynx again after apparent Google
spokespersons had posted in various lists that they had gone through
their services and thrashed out various accessability/usability
issues.
But when I tried to log in tonight to actually post,
it had all evaporated.
No matter what obstructions Google places in the way of my posting,
the browser is only a tool to get to the point of running vi
to enter the actual content.
Maybe they will go back and clean up these obstructions
to browser choice. There is nothing intrinsicly graphical or
javascript necessary to edit a blog post, so maybe this will change.
I will be checking into submitting via e-mail to get past this.
d.e.l. 2012 Apr. 23
All that was last night.
Now, I'm posting with Lynx no problem, but there is a warning that
the old interface will be gone by the end of the month.
I'll see what happens. I'm not trying to bad mouth Google,
they are trying to balance somewhat conflicting goals,
but I'm confident they will find a way.
d.e.l. 2012 Apr. 23

Sunday, November 8, 2009

zgv'ing Again

When I started the series of posts on console tools for PDF files, I had another computer, and it handled graphics from the console differently. The chipset on the old computer was directly supported by SVGAlib and everything was working fine as far as I was concerned. When I upgraded to the current computer I found many of the graphics programs I was using needed to be shifted over to using frame buffer drivers or versions, as the video chipset on this PC seemed to be marginally (or in some instances brittly) supported in Linux. In some instances this was a gain, one example being w3m, which I can if so choosing run as a graphical web browser. In a couple of instances, zgv and svncviewer, I had to do without a console program and use an X program.

zgv is one of the more amazing graphic applications that run from the raw console in Linux. Perhaps even more amazing than watching videos in a naked command line interface. It is an image viewer that can be used on single images, slide shows, or a directory of image files, handling most of the formats we are familiar with. It has some simple image processing capabilities, and when navigating a directory of images, can generate thumbnails of all the images and can present a graphical navigation interface with these thumbnails. The alternate viewer 'fbi' (Frame Buffer Imageviewer) if fine, but to date simply lacks some of the many capabilities of zgv. I first encountered zgv as a default image viewer for text browsers such as Lynx and w3m.

It's been over a year since I got the new computer, and the other morning, I decided to try to see if there was some way to revive use of zgv. It never failed to run, but in maybe half the images colors were distorted beyond reasonable use - something like solarization of color phototgraphic film - great if you want an LSD/Timothy Leary effect but not for daily use.

In the SVGAlib configuration file, I'd hardcoded use of the framebuffer driver (as opposed to SVGAlib choosing one of the supported chipsets) by uncommenting the line:


chipset FBDEV           # Use kernel fbdev, instead of direct hardware.

in the file /etc/vga/libvga.config. With this, applications that use SVGAlib will now indirectly use the video framebuffer. I rummaged around a bit through the zgv man pages, trying various things. One clue I searched on to see if there was something that might get it working consistently was the word 'force'. My notion was that perhaps something was being misinterpreted by the program and it 'forcing' some initial condition might solve the problem. I finally found a switch '--force-viewer-8bit' (or briefly '-j') that seems to do the trick. No solarization effects. It may be that some images could be displayed with greater sharpness or color accuracy, '8bit' throwing away parts of 16/24 bits of pixel information, but everything *looks* reasonable. Nothing is reduced to psychedelic poster (or even comicbook) appearence. The worst thing I've encountered so far is that after looking at information on the image file sometimes I need to refresh the display with a CTL-L or CTL-R, but this is a minor point. To make this default behaviour, edit the file /etc/zgv.conf and add the line:

force-viewer-8bit on

A few other settings I include in the file (you can look them up in the man page) are:

zoom on
centre on
auto-mode-fit on
jpeg-speed 1
mousescale 2.0
mouse on
block-cursor on
fs-perfect-cols on
jpeg-index-style 3
fs-thick-text on

A couple that apparently must be left out of the configuration file and placed among command line switches are:

#  show-dimensions on
# reload-delay 1000000
#   - fatal in this file

A few of the more important commands of zgv:

?        -  help
ESC      -  return to previous mode (eventually exiting)
Enter    -  go to the next image
v        -  toggle file selector mode between graphical or text
/        -  help for video modes available
:        -  display file information
;        -  reset brightness/contract/etc. to default
Alt-u    -  generate/update thumbnail images
Ctrl-I   -  start a slide show of files tagged in file selector mode.
Ctrl-R   -  refresh view/directory
Ctrl-L   -  refresh view/directory
Right Mouse button  -  context sensitive menu
Left  Mouse button  -  select an image or directory in file selector/directory view mode

You can navigate the file selector or large images with cursor, vi or (what I think are) WordStar keys. I leave exploring the various zooming, rotating, mirroring, flipping, contrast, brightness, gamma, rendering and file tagging capabilities to you, the reader. The ironic reality is that using this as the viewer for a text mode web browser, the surfer has more control over image viewing than any I've encountered with so called graphical web browsers.

A few of the command line switches can be of use. The '--reload-delay 100000' mentioned above effectively sets the default slide show interval to totally at the users decision to move on, instead of the default 4-sec. '--show-dimensions' (or -s) causes zgv to print the dimensions of displayed files to standard out, perhaps to pass on to some program for image processing. '-T' causes zgv to print the names of tagged files to standard out, where they could (for instance) be passed on via a script to CUPS and printed out, or copied/moved to a holding directory. And this really is the tie-in with these article with on .pdf. After using ghostscript to convert the pages of a pdf document to images, you can browse through them with zgv in file selector mode, tag some, and have them printed out.

Friday, October 2, 2009

With bmv ...

When I first started this series of posts on command line access to pdf files I had a different computer, one that was pretty compatible with SVGALib tools. The newer computer seems to work with SVGALib with extreme unpredictability. There seems to be decision 'out there' to not bother with keeping SVGALib current, to try and shift things towards use of frame buffers, which seem to work fine on the new PC> A while back I became aware of a frame buffer based tool for viewing postscript files called bmv. To take advantage of in pdfmenu, I added some lines:
alias PDFTOPS='/usr/bin/pdftops  '  ;
alias BMV='/usr/bin/bmv -m1 -v13 '  ;
    #       the -m/-v values were tuned by tests to what seemed
    #       to work best on my computer for typical .pdf files.
..........
 10 )
    THEPSFILE="${INSIDEFILE#/tmp/}"  ;
    THEPSFILE="/tmp/${THEPSFILE%.pdf}.ps"  ;
    RM  ${THEPSFILE}  ;
    PDFTOPS  ${INSIDEFILE}   ${THEPSFILE}  ;
    BMV      ${THEPSFILE}  ;
    RM ${THEPSFILE}  ;
    ;;
  
and appropriate entries to the select menu. bmv is fairly easy to figure out how to navigate. In general, I'm satisfied with it's job of showing .pdf files.

Monday, January 19, 2009

pdfmenu

As you may have figured out by now, I created a master script for handling pdf files when in text consoles. I've put this up at http://www.lafn.org/~aw585/pdfmenu. There are probably many improvements that can be made to this but it provides a simple way to attack pdf files.

firefox -new-tab ......

I used to use one of my 26 bookmark files of Lynx to pass URLs from web browseing in Lynx to Firefox. I had that particular file bookmarked by Firefox, and could simply bookmark a url to the "F" bookmarkfile from Lynx, then when I swapped to Firefox pull up that file from Firefox's bookmarks, then seek out the particular URL in question. I thought that was pretty slick, saving a lot of scratch paper moving the URL from a text console to GUI environment, but I've since done better.

Looking over the man page for Firefox, I found there was provision for sending URL's to already running instances of 'fox. After a bit of experimentation, I found that this could be done from text consoles, and was not restricted to being issued from the GUI environment. With this information, I added these lines to my Lynx externals in /etc/lynx-cur/lynx.cfg:

EXTERNAL:http:firefox -new-tab %s --display=\:0.0 ; sudo chvt 11 :TRUE

EXTERNAL:http:firefox -new-window %s --display=\:0.0 ; sudo chvt 11 :TRUE

The '-new-tab' and '-new-window' switches are pretty self explanatory. --display tells which X display to use, which could is theory be more complex than most people use. It should be pointed out that it was necessary to escape the colons with this parameter so as not to confuse Lynx. The part starting with 'sudo ...' might be unfamiliar to some. chvt is a command to switch to other virtual consoles. Currently it seems to be limited to those setup by inittab or it's equivalent, and requires root privilages to function. I've sudo configured to run it without needing any password. Anyway, one curious thing is that it can switch you to your GUI, which in my case is console 11 - you'd need to adjust it to your situation, usually console 7.

I'm putting this article in my series on handling pdf files in text consoles because you can use this to pass the location of a file to Firefox from a console and let it handle the file however you have Firefox configured to. The fact of the matter is though that almost any thing can easily be passed from Lynx to Firefox this way not just pdf files. This has accessability implications in that someone who may out of neccessity use Lynx can with this use Firefox as a simplified interface to running various media types in the GUI environment. They could have their GUI configured to automaticly launch FireFox when it starts, and perhaps set things up so that when finished the switch back to the console and restart X rather than bother trying to navigate the GUI. This is pretty crude, but it might serve their needs. One complication might be the need to locate a start button, such as sites like YouTube have, but perhaps even this might be overcome. Anyway only the future will tell.

5) with fbgs / Investigating fbi

When I started this series of articles on handling pdf in text consoles, I had a different computer, using different tools for video content in consoles. Since then I've started using a frame buffer, and a tool for using a frame buffer to view .pdf's, fbgs came to my attention. fbgs is actually a script to glue actions by ghostscript and fbi, "Frame Buffer Imageviewer" together. fbgs accepts most of the flags for fbi, and a few of it's own. The most significant of it's own, to me, seems to be '-c', to render in color. fbi itself is a fairly straightforward tool, the most important command when using it being 'h', to toggle the help display on/off. Once you've got the help displayed, you can do most anything with it. fbi seems to be more minimalist oriented where the svgalib using zgv imageviewer is a 'kitchen sink' tool, loaded with features. zgv can be compiled with sdl, "Simple DirectMedia Layer" support instead of straight svgalib, so that it can use framebuffer images display, but I haven't done that yet, and it is another story.

Saturday, August 2, 2008

5) dump to printer

Yet another option for looking at PDF files is the use of a special purpose viewing device refered to as a 'printer'. For those of you who may be unclear on the concept, 'printer's use special chemicals to permenantly lay down a copy of the image that would normally be seen on the screen onto a thin sheet of organic celluloid material ("paper"). Bulky and cantankerous at best, the quaint devices are capable of handling not only PDF files, but with appropriate device drivers, such data formats as text, jpeg, png, gif etc.

Below is a script for sending a PDF to a 'printer'. It is set to scale the file to maximize it's use of the paper, but could easily be modified to throw up a menu of scaling factors, typical might be 25%, 33%, 50%, 66%, 75% etc.


#!/bin/bash  -


# ############## security pack ##############################

PATH='/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin:/usr/games:~/bin'  ;


hash -r  ;
#  -  Bash Cookbook, 1st ed.,, #14.5

ulimit  -H -c 0 --  ;
#  -  Bash Cookbook, 1st ed.,, #14.6

IFS=$' \t\n'  ;
#  -  Bash Cookbook, 1st ed.,, #14.7

UMASK='002'  ;
umask  $UMASK  ;
#  -  Bash Cookbook, 1st ed.,, #14.8

\unalias -a
#  -  Bash Cookbook, 1st ed.,, #14.4

# ############## security pack ##############################

USAGE="$0  -h | file.pdf | file.ps  "  ;

VERSION='$Id'  ;

set -e  ;
shopt -s  nocasematch    expand_aliases  ;

# alias RM='/bin/rm  -f   2> /dev/null '  ;
# alias RMDIR='/bin/rmdir 2> /dev/null '  ;
# alias MKDIR='/bin/mkdir 2> /dev/null '  ;
# alias EZGV='exec   /usr/bin/zgv'  ;
#  alias ZGV='/usr/bin/zgv'  ;
alias LPR='/usr/bin/lpr -o scaling=100%  '  ;


THEPDFFILE=${1}  ;

case  ${THEPDFFILE}  in
[-/][h?]* )
  echo 'Usage: '${USAGE}  ;
  exit  ;
  ;;
[-/]v* )
  echo ${VERSION}  ;
  exit  ;
  ;;
*.ps )
  THETTAG=${THEPDFFILE%.ps}  ;
  ;;
*.pdf )
  THETAG=${THEPDFFILE%.pdf}  ;
  ;;
* )
  exit  ;
esac

if [ ! -f ${THEPDFFILE} ]  ; then
   echo 'File needed'  ;
   echo ${USAGE}  ;
   exit  ;
fi

LPR  ${THEPDFFILE}  ;



exit  ;

Friday, August 1, 2008

4) individual embedded images

The following script extracts each individual image embedded in a PDF document and displays them. As documented in the script, it is based on a tool I recently became aware of from a "Tech Tip" in Linux Journal. The tool, pdfimages, extracts the individual images from the PDF document, which are then viewed using zgv. I call this script 'pdfimagesview'.


#!/bin/bash  -


# ############## security pack ##############################

PATH='/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin:/usr/games:~/bin'  ;


hash -r  ;
#  -  Bash Cookbook, 1st ed.,, #14.5

ulimit  -H -c 0 --  ;
#  -  Bash Cookbook, 1st ed.,, #14.6

IFS=$' \t\n'  ;
#  -  Bash Cookbook, 1st ed.,, #14.7

UMASK='002'  ;
umask  $UMASK  ;
#  -  Bash Cookbook, 1st ed.,, #14.8

\unalias -a
#  -  Bash Cookbook, 1st ed.,, #14.4

# ############## security pack ##############################

USAGE="$0  -h | file.pdf | file.ps  [ startpage# [ endpage# ] ]"  ;

VERSION='$Id: pdfimagesview,v 1.1 2008/07/08 09:20:30 dallas Exp dallas $'  ;

set -e  ;
shopt -s  nocasematch    expand_aliases  ;

alias RM='/bin/rm  -f   2> /dev/null '  ;
alias RMDIR='/bin/rmdir 2> /dev/null '  ;
alias MKDIR='/bin/mkdir 2> /dev/null '  ;
alias PDFIMAGES='/usr/bin/pdfimages'  ;
alias EZGV='exec   /usr/bin/zgv'  ;
#  alias ZGV='/usr/bin/zgv'  ;

#  pdfimages is from the poppler-utils package,
#  referenced in 'Linux Journal' May, 2008, p. 83, Tech Tip
#  'Extract Images from PDF Files', Matthew Martin.
#  It extracts the images from a pdf file


THEPDFFILE=${1}  ;

case  ${THEPDFFILE}  in
[-/][h?]* )
  echo 'Usage: '${USAGE}  ;
  exit  ;
  ;;
[-/]v* )
  echo ${VERSION}  ;
  exit  ;
  ;;
*.ps )
  THETTAG=${THEPDFFILE%.ps}  ;
  ;;
*.pdf )
  THETAG=${THEPDFFILE%.pdf}  ;
  ;;
* )
  exit  ;
esac

if [ ! -f ${THEPDFFILE} ]  ; then
   echo 'File needed'  ;
   echo ${USAGE}  ;
   exit  ;
fi

if [[  ${THETAG} == */* ]] ; then
  THETAG=${THETAG##*/}  ;
  fi  ;

THEDIR1='/tmp/pdfimages'  ;
THEDIR2="${THEDIR1}/${THETAG}"  ;
THEFILES="${THEDIR2}/${THETAG}"  ;

for ii in ${!THEDIR*}
do
if [ ! -d ${!ii}  ] ; then
  RM      ${!ii}  ;
  MKDIR   ${!ii}  ;
fi  ;
done  ;

RM  ${THEDIR2}/*  ;

PDFIMAGES -f ${2:-1} -l ${3:-200}  ${THEPDFFILE} ${THEFILES}  ;

EZGV  --visual ${THEDIR2}/   ;



exit

Tuesday, July 15, 2008

3) One image/page

This is the first method I recall using to look at .pdf files from the command prompt. Basicly, it simply uses Ghostscipt to convert a page into a graphic, and then view it with zgv, an SVGAlib based image viewing tool. When I rethought this through a few days ago, and set it up as the current script below, I modified it to handle more than one page, and in the process, studied capabilities of zgv I was only vaguely aware of.

    Basicly, zgv has two modes of operation
  • Browser Mode, capable of navigating and operating within the file system
  • Viewer Mode
      The viewer mode has two self explanitory subdivisions
    • Single image mode
    • Slide show mode

    Some of the key underdocumented commands. These are just the ones I think most important not in the help mode.
  • ? - context sensitive (but incomplete) help mode
  • u - create thumbnails for use in browse mode
  • n/t - un/tag image files
  • N/T - un/tag all image files
  • ^I (TAB) - Kick into slide show of all tagged files
  • Return - Go from browse mode to viewing mode for an individual image
  • Escape - Go from viewer mode back to browse mode
  • Alt-f - show number of image files and tagged image files in the current directory
  • : - show details about image file cursor is on

zgv may not be the GIMP or Photoshop, but it has much more capability than to simply throw an image on a console screen. I call the script below pdfgsview.


#!/bin/bash  -


# ############## security pack ##############################

PATH='/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin:/usr/games:~/bin'  ;


hash -r  ;
#  -  Bash Cookbook, 1st ed.,, #14.5

ulimit  -H -c 0 --  ;
#  -  Bash Cookbook, 1st ed.,, #14.6

IFS=$' \t\n'  ;
#  -  Bash Cookbook, 1st ed.,, #14.7

UMASK='002'  ;
umask  $UMASK  ;
#  -  Bash Cookbook, 1st ed.,, #14.8

\unalias -a
#  -  Bash Cookbook, 1st ed.,, #14.4

# ############## security pack ##############################

set -e  ;
shopt -s  nocasematch    expand_aliases  ;

alias RM='/bin/rm -f  2> /dev/null '  ;
alias MKDIR='/bin/mkdir  2> /dev/null '  ;
alias LS='/bin/ls -A  2> /dev/null '  ;
alias WC='/usr/bin/wc -l  2> /dev/null '  ;
alias GS='/usr/bin/gs'  ;
alias EZGV='exec   /usr/bin/zgv'  ;

USAGE="$0  -h | file.pdf | file.ps"  ;

VERSION='$Id: pdfgsview,v 1.3 2008/07/08 11:22:38 dallas Exp dallas $'  ;

THEPDFFILE=${1}  ;

case  ${THEPDFFILE}  in
[-/][h?]* )
  echo ${USAGE}  ;
  exit  ;
  ;;
[-/]v* )
  echo ${VERSION}  ;
  exit  ;
  ;;
*.ps )
  THETAG=${THEPDFFILE%.ps}  ;
  ;;
*.pdf )
  THETAG=${THEPDFFILE%.pdf}  ;
  ;;
* )
  exit  ;
esac


if [ ! -f ${THEPDFFILE} ]  ; then
   echo 'File needed'  ;
   echo ${USAGE}  ;
   exit  ;
fi

if [[  ${THETAG} == */* ]] ; then
  THETAG=${THETAG##*/}  ;
  fi  ;

THEDIR1='/tmp/pdfgsimages'  ;
THEDIR2="${THEDIR1}/${THETAG}"  ;
THEFILES="${THEDIR2}/${THETAG}.%03d.png"  ;

for ii in ${!THEDIR*}
do
if [ ! -d ${!ii}  ] ; then
  RM      ${!ii}  ;
  MKDIR   ${!ii}  ;
fi  ;
done  ;

RM  ${THEDIR2}/*  ;

#  THETEMP="/tmp/${THETEMP##*/}"  ;
RM     ${THEDIR2}/*.png  ;

GS -SDEVICE=png16m -sOutputFile=${THEFILES} -  ${THEPDFFILE}    <<QUIT
QUIT

count=$( LS ${THEDIR2} | WC )  ;

case ${count}  in

1 )
  EZGV    ${THEDIR2}/*.png  ;
  ;;

* )
  EZGV     ${THEDIR2}/  ;
  ;;

esac  ;

exit  ;

The 'security pack' mentioned above are some suggested actions to improve script security mentioned in the O'Reilly 'bash Cookbook'. There are others in the book, but these I judged 'no-brainers', in that they can simply be included and don't seem to even require understanding or any modification to use.

Sunday, July 13, 2008

2) As text

One approach to viewing .pdf files is presented in the O'Reilly book http://oreilly.com/catalog/9780596009113/index.html|"Linux_Desktop_Hacks". In the first edition, Hack #53, p. 170, "Display PDF Documents in a Terminal", gives a script that uses pdftohtml and elinks to view the text in pdf documents. Below is my variation on their viewpdf, I call it pdfview.


#!/bin/bash  -


#  per ORA  Linux Desktop Hacks  #53
#  with the following line added to '/etc/mailcap':
#  application/pdf; /usr/local/bin/pdfview '%s'; needsterminal; description=Portable Document Format; nametemplate=%s.pdf
# $Id: pdfview,v 1.5 2008/07/14 02:19:18 root Exp root $


#  pdftohtml -q -noframes -stdout ${1} | elinks -force-html
# does not work: pdftohtml -q -stdout ${1} | elinks -force-html

ABSOLUTE=${1:0:1}  ;

case ${ABSOLUTE} in
/ )
  PREFIX=''  ;
  ;;
* )
  PREFIX="${PWD}/"  ;
  ;;
esac

WORKFILE="$(mktemp -p /tmp XXXXXXXX).html"  ;
while [ -a ${WORKFILE} ]
do
  WORKFILE="$(mktemp -p /tmp XXXXXXXX).html"  ;
done

#     -- apparently pdftohtml requires the file end in '.html'

SOURCEFILE="${PREFIX}${1}"  ;

cd /tmp

pdftohtml  -q -nodrm  "${SOURCEFILE}"   ${WORKFILE##*/}  ;

exec elinks -force-html   ${WORKFILE}  ;

Saturday, July 12, 2008

1) General info

Doing a 'man -k pdf' generated a list of pdf related data for my Debian system. One that stood out was pdfinfo.

/usr/bin/pdfinfo -meta -box  <filename>

Seems to generate most of the info you'd want about a pdf, but one exception I noticed was nothing on the number and types of embedded images. It also seemed to need some blank lines thrown out to keep all the information together.

Thursday, July 10, 2008

Window Beyond a Plateau, Window Into Windows

I recently had reason to use VNC, Virtual Network Computing and then while using GRML, noticed something, a mention of a VNC client, that aroused my curiosity, and made me decide to do some googling on the subject. A search of the Debian packages turned up a couple of 'console' based VNC clients that did not require X. These obviously would need some kind of graphical interface, but in the case of svncviewer and directvnc, these were SVGAlib and framebuffers respectively.

Not using a framebuffer on my PC, I installed svncviewer and tried using it. At first it didn't seem to work, but studying the error messages it gave, there was some hint that the graphic modes available for it weren't in line with what the VNC server needed. I was puzzled at first, trying various parameters suggested by the svncviewer man pages, but then remembered that there was a configuration file for SVGAlib, /etc/vga/libvga.config in the case of my Debian computer. I edited this, loosening up everything I could as far as the video went to allow the maximum resolutions suggested by the comments in the file.

This worked great, svncviewer began working, connecting to both Linux X desktops and Windows boxes. The act of editing this configuration file jogged my memory that when I'd originally started using SVGAlib on the computer I was using a monitor already long obsolete when I took possesion of it, and had finally gave out and had been replaced with something more reasonably up to date. In other words, updating the SVGAlib settings was long overdue.

The most obvious initial problem was that the mouse seemed impossibly difficult to work with on the virtual console used by svncviewer. With adjusting the SVGAlib video settings so fresh in mind, I tinkered with the mouse settings in the config file. Part of the problem was that I'd try to move the mouse slightly and it would jump to the other side of the screen or do other crazy things, only occasionally doing what was desired. This all apparently fell under the description of 'accleration' from what I could figure out from the configuration file notes. Without going into specifics, which will undoubtedly differ from case to case, I found I could adjust the trip point and amount of 'accleration' to make the mouse move smoothly, problem solved. These settings solved problems with applications other than svncviewer, notably the links2 browser. Now the mouse was more usable with it as well, and the higher resolution put more of a web page on the screen at one time.

As a test for using this in the real world, there was a MS Window machine I needed to start using, but real world phyisical deskspace is at a premium. I managed to get the machine connected, reasonably close to my personal desktop workstation, and then get a VNC server installed on it. VNC doesn't seem to do anything to link up the audio I/O, only video, keyboard and mouse/pointer, so I connected it to my workstation with some 99 Cents only audio patch cords in addition to putting on the Ethernet LAN. (Anyone know of any 'virtual patchcord' application that could replace these?) On boot up, the VNC connection seemed to start early enough to catch request for a 'Ctl-Alt-Del' entry to get to the graphical login prompt. This I had to reach over and enter from the Windows machine keyboard, but everthing else has seemed to work one way or the other from the svncviewer. Some online documents hinted at possible problems for svncviewer connecting to Windows boxes due to some palete problem, but that doesn't seem to happen with the version I have installed. Using everything involved, I've been able to use the Skype client on the Windows machine to place and recieve calls, and fire up FireFox on it, and set up/handle an account for one of my bills online.

There was some mention online of a bootable Linux floppy disk with svncviewer on it, for an ultra-light X desktop, and I've conducted some experiments with setting svncviewer up on a console in /etc/inittab. (This last might require some addition to the autologin script, putting some sleep delay to prevent excessive respawning from inittab triggering a temporary lock on the virtual console if the server it's pointed at isn't immediately available, but seems like a problem that can be dealt with.) At the very worst, svncviewer provides a remote monitor, with occasional need to get the actual keyboard of the machine you connect to. So far I haven't found F8 or any other keyboard combinations to get to any menus or whatever, as was suggested for other VNC viewers, but this can be dealt with. But basicly, it works. It has me thinking about setting up an X/GUI server.

Friday, July 4, 2008

A Summer Day's Thoughts on Prague Spring

Being the Fourth of July, it seems particulary appropriate to mention a few updates on my earlier post, http://isthereanotherquestion.blogspot.com/2007/12/streetnoise.html.

A few YouTube videos I'd linked to have been removed, no great loss, since there were several to choose from anyway. But...

A couple of more videos have been put up for music off Streetnoise, one hardly qualifying as a "video", but the other, is quite different. The creator put some effort into matching up some news footage of the time with "Czechoslovakia", documenting a 'loss of independence day'. I thought this was important enough to call attention to it in this seperate blog notice, to call attention for a few minutes today to the memory of Alexander Dubcek. He might not be another Milton Friedman or Ludwig von Mises, but he figured out a few decades before Mikhail Gorbachev that 'the system' was not working. For this he belongs in the international pantheon of freedom lovers, along with Jefferson, Adams, Franklin etc.

Wednesday, July 2, 2008

Windows and Cups

These are some notes I came up with a few years ago, for connecting Windows machines to CUPS printer servers. This may have been on my web site or somewhere at one time, and I just wanted to make it available for reference.




Install the CUPS daemon on the printer server computer.
Configure the printer via the web interface at

http://localhost:631/

This is not covered by this document but the web
interface is fairly straight forward.

On the CUPS printer server
*************************

a) On the CUPS printer server
   make some changes to the CUPS config per
   http://www.faqs.org/docs/Linux-mini/Debian-and-Windows-Shared-Printing.html
   on the CUPS server.

   1) in /etc/cups/mime.convs
      uncomment:
      application/octet-stream   application/vnd.cups-raw   0   -

   2) in /etc/cups/mime.types
      uncomment:
      application/octet-stream

   3) In /etc/cups/cupsd.conf per
      http://localhost:631/documentation.html
      This is using the suggestions in the Linux Cookbook,
      by Carla Shroder, ORA, p. 247
      and somewhat more restrictive than the suggestions
      by the mini-Howto referenced above, and needed for
      all clients anyway, whatever the OS the clients run:

      LogLevel info

      Port 631

      Put:

      <Location /printers>
      Order Deny,Allow
      AuthType None
      Deny From All
      Allow From 127.0.0.1
      Allow From 192.168.1.*
      #    -- or whatever is appropriate for the LAN
      </Location>


At the windows end:
*********************

b) get the ethernet cable to it  :-)

c) make sure the Internet Printing Services is installed
   (from Linux Cookbook, by Carla Shroder, ORA p. 249
   This will require the Windows installation CD
   For Windows 95/98 this can be downloaded from
   http://www.microsoft.com/windows98/downloads
   look for "Internet Print Services", wpnpins.exe

   Windows ME is in the Add-on folder on the installation CD

   Windows NT, go to Control Panel -> Network -> Services tab
   -> Add Microsoft TCP/IP Printing

   Windows 2000/XP go to Network and Dial-up Connections ->
   Advanced Menu -> Optional Networking Components ->
   Other Network File and Print Services

   If it acts squirrely when you try to install the driver,
   it may be because the driver is already installed,
   either by default on OS installation/upgrade or perhaps
   someone else took care of it.

d) go to printer/fax setup on the windows machine,
   add a new printer, select network printer, enter the URL
   for example:

   http://192.168.1.1:631/printers/theprintername

   or if DNS resolution is available to the print server

   http://www.somewhere.com:631/printers/theprintername

   and finish up.

   Breakdown of this URL:


         IP address or name of the CUPS printer server
         as needed/appropriate.

         '631' is the port of IPP and http interface to the
         CUPS server on typical CUPS installation

         '/printers/'  the directory the printers appear
         to be in, probably defined by the <Location...>
         statement mentioned above in a.3 .
         This seems to be a typical setting for this printer.

         'theprintername' points it the printer on that server
         a fairly arbitrary name defined in the CUPS configuration
         of the printer (not covered in this article,
         but just handled at the web interface in
         http://localhost:631/)

         I saw this stuff in a comment at:
         http://www.linuxjournal.com/article/8618

d) select the printer model (HP LaserJet 6P in this case)
   and things are ready to rock&roll....

Thursday, June 26, 2008

Lynx HTTP EXTERNAL Menu Script

One thing keeping my friend Larry from getting the most out of my usnatch program and Lynx externals is awkwardness he has in dealing with the EXTERNAL selection menus. He is blind and this coupled with many of the long, complex URLs, (in many cases having stretches of random hash characters) that are passed to the Lynx EXTERNAL menu for special handling make it hard for him to seperate out the choices the menu presents. He literally can't wade through the URLs to get to the menu selection options. This is different from many of the other Lynx menus, where simple brief descriptions of the choices are given, without interjecting the names of temporary files and such into the options to confuse the issues.

To try and deal with this problem, I present a bash script below to replace a collection of Lynx EXTERNAL entries for http with a single entry, that presents a simplified menu. This whole idea is a variation on what I documented in my article Lynx/Kermit Coordination Part I hosted by the Kermit Center at Columbia Univesity. This script will have to be customized, and a seperate one would have to be created for other protocols such as ftp, ssh, irc and such. I've put extensive notes in this script, since I think it makes explination simpler if the notes are close to the subject instead of before or after in this blog's narrative. Also, the people using it might not be familiar with bash, so I try to explain as much as I can, so they can knowledgably change it to their needs.

To install this script, first make sure your version works from the command promt. Then comment out all the

EXTERNAL:http:....

statements in your lynx.cfg file, both any in your home directory, and those in /etc/ and it's subdirectories, adjust the script to include those possibilities you want in it, and put a single EXTERNAL statement:

EXTERNAL:http:extern.menu %s:TRUE

Where extern.menu is taken to be the name of the menu script.

I've put a copy of this script online at a Yahoo group for Larry's friends, http://groups.yahoo.com/group/larryhsfriends/


#! /usr/bin/env bash
#  #!/usr/bin/bash  -

#  '#! /', env per
#  'bash Cookbook', 1st edition, recipe #15.1, p. 321
#  "Finding bash Portably for #!"
#  http://www.bashcookbook.com
#
#  trailing '-' per
#  'bash Cookbook', 1st edition, recipe #14.2, p. 283
#  "Avoiding Interpreter Spoofing"

#  the first line convention points to the intepretor to be used.

#  Some bash conventions for beginners:
#
#  hash/pound/sharp/octhorps to the end of line are comments.
#
#  Lines ending exactly with a backslash, '\', are continued
#  with the next line.
#  Trailing whitespace after the backslash can cause errors,
#  so beware of it.
#
#  I urge you to look up aspects of this script,
#  either with man bash, or if you are running bash
#  at your command prompt, with the help command
#  such as 'help case' or 'help select'.

URL="${1}"  ;

PS3='What EXTERNAL action do you want? '
#         -- defaults to '#?'
#            trailing blank desirable for spacing of response
#            from prompt
#            PS3 is the Select Menu Loop prompt in bash

#  Note 'for' statement like syntax of select:

select external_action in       \
      'Quit externals                                              '          \
      'Print the URL'           \
      'USnatch'                 \
      'lynxvt'                  \
      'screened-lynx'           \
      'javascript-links2'       \
      'graphical-links2'        \
      'W3M'                     \
      'links'                   \
      'elinks'                  \
      'Blogspotviewer'          \
      'lynx-noreferer'          \
      'lynx-nofilereferer'      \
      'Privoxy Control Panel'   \
      'Microbookmarker'         \
      'wget'                    \
      'Bug-Me-Not'              \
      'whomis'                  \
      'nspeep'                  \
      'pingvolley'              \
      'lynxtab'                 \
      'lynxtab-blank'           \
      'lynx-blank'              \
      'frys'                    \
      'bash'

#    Note: the last select menu item should not and a trailing
#    '\' to continue on to the next line.
#    I've placed each menu item or quoted phrase on a seperate
#    continuation line.
#    At this point, it is normally desirable to have one menu item
#    for each of the case statement stanza's below.
#    They don't need to be in order.
#    There just has to be a menu prompt item
#    and a case "whatever )" that match
#    so the case stanza can be triggered.
#    Be careful in using '*' 'splat' patterns,
#    that you do not unintentionally match more than
#    the desired pattern by mistake.
#    This could accidently short circuit desired action,
#    keeping a case stanze from being taken when wanted,
#    and causing another to be taken instead.
#    If all the menu items are short, select will try to put
#    them in multiple columns.
#    Only one item needs to be wide, (which can be because of trailing
#    blanks) to trigger single column menu display.
#    In this case, I used the 'Quit' item to do this with,
#    since it is basicly matched for the most part with a '*'
#    keeping the line in the case statement a reasonable length.
#    The menu items are only needed to clue the user on the
#    significance of each number chosen,
#    and to tie that to the case stanza.
#    Alternatively, you can keep the menu items in a strict order,
#    and use 'REPLY' for the case variable, in which case
#    each case stanza would be picked on the basis of the
#    number selected from the menus instead of patterns
#    that match the menu item strings.
#    In this case, ordering is critical.

#    Many of these actions are special purpose scripts I have
#    written and are included here just to provide a realistic
#    example.
#    The size is probably excessive for some people.
#    This script will certainly have to be customized to your
#    personal needs.

do

  case ${external_action} in

  #  item between 'case' and 'in' undergoes
  #  several levels of evaluation before
  #  the case statement is finally executed.

  #  Case stanza's start with
  #  string_to_match )
  #  list of actions ;
  #  break  ;   # include a break statement to break out of the
  #             # select menu loop
  #  ;;    #  double semicolons  end actions and stanza
  #

  Q* )
    echo 'Returning to browsing'  ;
    break  ;
    #  Thumb rule in this sort of script is
    #  that a break is needed whenever there
    #  is no exec statement in a case stanza.
    #  This stops the select loop after a decisive action.
    ;;

  P* )
    read -p "The URL in question: ${URL} "  TRASH  ;
    break  ;
    ;;

  USnatch )
    exec    usnatch  ${URL}  -i -p  ;
    #  break is not needed after an exec statement
    #  because this script's process, including
    #  the select loop is replaced
    #  by the action of the exec statement,
    #  ending the select loop.
    #  You could put a break after each exec,
    #  it would probably be excessively cautious,
    #  since it would only be executed under bizarre conditions.
    ;;

  lynxvt )
    #  exec    lynxvt  ${URL}  &  ;
    exec    lynxvt  ${URL}    ;
    ;;

  screened-lynx )
    screen -t 'lynx ...' lynx   \
        -useragent='Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)'  \
        ${URL}    ;
    break  ;
    ;;

  javascript-links2 )
    screen -t 'jlinks'  \
        links2 -enable-javascript 1 -html-numbered-links 1  \
        ${URL}    ;
    break  ;
    ;;

  graphical-links2 )
    sudo links2 -g -driver svgalib -mode 640x480x256   \
        -enable-javascript 1 -html-numbered-links 1    \
        ${URL}    ;
    break  ;
    ;;

  lynx-noreferer )
    exec  lynx -noreferer=off -tna ${URL}    ;
    ;;

#    start of a typical case stanza:
  lynx-nofilereferer )
    exec  lynx -nofilreferer=off -noreferer=off -tna ${URL}  ;
    ;;
# end of the typical case stanza

  Privoxy* )
    screen -t 'Privoxy Control Panel'   \
      lynx -nofilereferer=off -noreferer=off  \
      -tna 'http\://config.privoxy.org'   ;
    break  ;
    ;;

  Microbookmarker )
    exec  microBkMrk ${URL}  ;
    ;;

  Blogspotviewer )
    exec  blogspoter ${URL}  ;
    ;;

  [Ww]3[Mm] )
    exec  w3m ${URL}  ;
    ;;

  links )
    exec  links ${URL}  ;
    ;;

  elinks )
    exec  elinks ${URL}  ;
    ;;

  wget )
    exec  nohup wget  --background -a ~/wget.log -P /mnt/hda8/  ${URL}  ;
    ;;

  Bug-Me-Not )
    screen -t Bug-Me-Not   \
       lynx -cookies www.bugmenot.com/view.php?url=${URL}  ;
    break  ;
    ;;

  whomis )
    exec  whomis  ${URL}  ;
    ;;

  nspeep )
    exec  nspeep  ${URL}  ;
    ;;

  pingvolley )
    exec  pingvolley  ${URL}  ;
    ;;

  lynxtab )
    exec  lynxtab  ${URL}  ;
    ;;

  lynxtab-blank )
    exec  lynxtab    ;
    ;;

   lynx-blank )
    exec  env -u HTTPS_PROXY='' lynx -tna -accept_all_cookies    ${URL}  ;
    ;;

  frys )
    #  to send pdf's straight to a printer
    #  this script has mainly been used for Fry's Electronics
    #  online version of their newspaper ads.
    exec  lprfrys  ${URL}  ;
    ;;

  bash )
    #  this is just to explore the environment that the
    #  externals run in
    exec  bash -i  ;
    ;;

  * )
    # if something unexpected happens,
    # this catchall stanza should simply end the script.
    # '*' matches anything at all, after all other
    # patterns have been given a chance to match.
    # it is customary to include this
    # at the end of bash case statements.
    break  ;
    ;;

  esac     #  'case' backwards marks the end of the case statement

done       #  this done statement marks the end of the select menu loop

exit  ;  #  just to make sure!  :-)

Thursday, June 19, 2008

RAND, The Corporation and It's Non-shareholders

11 June 2008 I attended another ALoud talk at the Los Angeles Public Library. The topic that night, "Soldiers of Reason: The RAND Corporation and the Rise of the American Empire".

When I was in college, the idea of working for a 'think tank' was very appealing. I read some early book on the phenomenon, and naively thought of think tanks as an extension of the college dormatory all night yak session. The speaker was not totally negative about RAND, but pointed out that they had successes on some studies, failures on others. Most people don't realize that today it is not the little Dutch boy plugging the dike hole that keeps Holland from getting flooded, but a RAND Corp. study.

The speaker grabbed my attention when in the first few minutes of the talk phrases like 'Ayn Rand', 'Milton Friedman', 'Chicago School of Economics' and 'logical expectations' were brought up. The speaker criticized a lot of RAND's studies and results as being flawed by describing people as 'logical actors'. He mentioned the idea, as an example, that Corporations only have a duty to maximize profits for their shareholders.

This may have been an underlying belief at RAND, but to associate such naive ideas with Milton and the 'Chicago School' is doing them a disservice. Economist's have long been dealing with the idea of 'externalities', what the others might call side effects. Prominently, Ronald Coase of the University of Chicago developed the so called "Coase's Law" to provide a guide on this topic.

But actually, you can understand the idea by a simple observation. Maximizing the profits of the shareholders may be the most obvious goal of a corporation, but they clearly have others. There are usually more non-shareholders than shareholders, and not provoking them into a lynch mob out to destroy the corporation and it's owners is clearly something they have to keep in mind. 19 June 2008

Monday, June 9, 2008

A bash Tool

I was writing a bash script the other day, and got fed up with having to take seperate steps to handle a lot of the routine steps to make it useable. So, I piled them all together. This bundles together several ideas I been exposed to in the last week.



#!/usr/bin/env  bash

#     -  See 'man env' and the discussion involving 'env'
#        and invoking Perl
#        in "Programming Perl", by Larry Wall

#   bcmp, Bash "CoMPiler"
#   this program really just runs some housekeeping
#   chores you should do before trying to run a bash script.
#   This is partly inspired by a discussion of software
#   configuration management I read somewhere
#   (source forgotten) discussing the nightly 'build'
#   of some perl scripts, which rather than compiling them
#   they were put through regressions tests to verify they
#   were ready to run.
#   Many of the commands used in this were things I'd come
#   across lately that seemed to fit in with this idea.
#
#   7 June 2008 Dallas E. Legan II

USAGE="${0##*/}   -h | <script>"  ;

THESCRIPT=${1:?"What script file? Usage: ${USAGE}"}  ;

[ -f ${THESCRIPT} ]  || { echo ${USAGE}  ; exit ; }   ;

set -e    ;

#     - This causes bash to go into 'abort on command error' mode
#       See "Linux Journal", Feb. 2008, p. 10, "Letters"
#       "mkdir Errors Even More Trivial", Ed L. Cashin
#       http://www.linuxjournal.com/article/9957
#       This is also documented in 'man bash' and 'help set'
#       in somewhat obscure, too understated a way.
#       9 July 2008 addition:
#       This is also referenced in
#       the "bash Cookbook",
#       Carl Albing, JP Vossen & Cameron Newham
#       O'Reilly, (C) 2007
#       ISBN-10: 0-596-52678-4
#       ISBN-13: 978-0-596-52678-8
#       http://www.bashcookbook.com/
#       p. 75 - 76
#       Recipe 4.6 "Using Fewer if Statements"

sed  -i 's/ *$//'   ${THESCRIPT}  ;

#      - to strip out trailing blanks, particularly annoying
#        after '\'   'line continuations'
#        '-i' causes 'editing in place'.
#        (Addition 1 July 2008:)
#        I came across another reason for this
#        in the "bash Cookbook",
#        p. 57 - 59,
#        Recipe 3.3 "Preventing Weird Behaviour in a Here-Document"
#        'trap' on page 59 in particular.
#        Basicly, trailing spaces on here document delimiters
#        can cause a bad day.
#        --
#        Alternatively, this might be done using
#        'ed', to make it more traditional and portable.


#       For now, I'm leaving out this idea,
#       but you might want to install some commands
#       to verify that the number of
#       '('  == ')'   (outside 'case' statements)
#       '['  == ']'
#       '{'  == '}'
#       Total number of "'" and '"' are even, etc.
#       Seperate checks for these might make
#       make interpreting the results easier to figure out.

chmod  ugo+x   ${THESCRIPT}   ;

#     - simply to set the permissions to executable

bash -n  ${THESCRIPT}  ;

#     - to do a simple syntax check
#       per the "bash Cookbook",
#       p. 476 - 477
#       Recipe 19.12 "Testing bash Script Syntax"
#       also 'man bash' and 'help set',
#       where this is obscurely documented.

cp ${THESCRIPT}   ~/bin/   ;

#     - Lastly, copy the script to a directory in PATH,
#       this could be any satisfactory location.

#       You might also want to check the script into some
#       version control system at this point,
#       or runs some functional/regression tests.

echo  ${THESCRIPT}   seems ready to run    ;
#  9 July 2008 addition:
#  This is an idea Garth told me about while at
#  Rockwell - when it doesn't conflict with the
#  purpose of the program, it's good to have a
#  message telling if it succeeded or not.
#  This was in the mainframe world,
#  and this can conflict with the needs of
#  Unix programs, but a good idea when practical.
#        END OF SCRIPT