Hits since 2022-03-19 02:46:12:

Rosevear Software

What does it do?:

Let me explain...
I made SAM to solve some programming and software management problems.  Let me explain...

The Problems
Scripts can be used to do things to the environment, but they have to be sourced.  Sourcing is alright, but it is a nuisance to have to type "." in front each time you use such a script.

There are some things that a function does better than a script, such as dealing with passed arguments (parameters).  And functions don't need to be sourced.  They operate on the current environment.

The problem with a function is handling the function definition.  It needs to be sourced, if the function is to be made available in the current environment.  Once this is done the function becomes available in the current command set, and it can operate on the current environment.  This is good, except for the problem above, sourcing the definition.

There is a second problem.  Command sets are especially useful if they are changeable.  This means that besides sourcing the function definitions, the functions that were previously in effect need to be unset when the command set changes.  That way different command sets can be made available for different purposes.  The same command may have different meanings depending on the context--the command set to which it belongs.  Further, if command sets are used in this way, it reduces the total number of commands available at one time which makes them easier to deal with and allows one to understand the command sets in a chunked or abstract way which is good conceptually.

A third problem is this:  It would be good if one had a command which was always available and when entered gave a menu of the commands in the current changeable command set.

Finally a fourth problem is the need for a stack.  One selects a command set and uses it.  It would be nice if, when one is done with a command set, there was a way to return to the previous command set.

Providing a menu was an easy problem to solve.  The other three problems took some work.  Plus, I wanted to include ordinary shell scripts in the changeable command sets and I wanted this system to be usable from Bash command line (thus it would cooperate with Bash and could be referenced from scripts and functions).

The Solution
I solved these problems by using a directory based system.  A command set lives in a directory.  The text of the menu that describes the command set is in a file in that directory called menu.dat.  The function definitions for the command set live in files with rwx permissions of 644.  They have names that end in ".f" or ".sam".

The ".f" files define functions that remain available.  More specifically, the functions defined by .f files remain actively available during the SAM session.  I have placed .f files in two directories (but they could be used anywhere).  One is $sam and the other is $sam_tool.  Directory $sam contains executables (scripts and binaries) that are fundamental elements of SAM.  For example, a shell script called "menu" lives there.  It, of course, displays the menu for the current command set when entered.  Directory $sam also contains .f files, as I said already, that define basic SAM functions.  Directory $sam_tool is similar to $sam, except that what it contains is not fundamental to SAM (tools rather than basic function).  SAM keeps both of these directories in the PATH variable which keeps the executables in them actively available.  Thus the functions defined by .f files in these directories _and_ the executables in these directories both remain actively available during the SAM session.

The ".sam" files define functions that are only available when SAM has changed the PATH variable such that it includes the directory that contains the .sam files.  This clever bit of trickery is done so that the functions defined by .sam files in a directory are actively available when and only when the executables in the directory are actively available.  SAM's command "bound" is used to control the PATH variable (and actively available functions and executables) in this manner.  Command bound, by the way, is a function defined by the file $sam/bound.f, thus it is defined by a .f file in $sam.

There are two scripts and two functions that I need to describe.  The scripts are unfun and funfun.  Both of these are created and sometimes updated by function dofun.  dofun is the only function in $sam that is not an .f file.  It sources the .f and .sam files, so therefore cannot be one itself.  Read more about this below.  Scripts unfun and funfun are similar (yet different).  unfun is used whenever the command set is changed by bound or bye.  (Actually bound runs sam_shel which runs unfun.  Similarly bye runs pop which runs unfun.) bound changes to a new command set and bye returns to the previous command set.  unfun is invoked to wipe the function definitions before they are set anew by function dofun.  Then name "unfun" means "undo functions".  funfun is similar, but it is only invoked when SAM is started.  It thus removes inherited function definitions.  This is especially for cases when SAM is started recursively inside itself.  Its name means ".f undo functions".

The two functions I need to describe are upfun and dofun.  (I've already talked about dofun above.) upfun is a convenient function that first runs unfun and then dofun.  So doing it is responsible for:  (1) Unsetting the ".sam" functions defined by a previous use of bound, (2) sourcing the new function definitions, and (3) maintaining file $sam_temp_dir/unfun.  (dofun can also maintain $sam_temp_dir/funfun, but it doesn't do it in this case.  It normally writes to funfun only when SAM is started.)

The sourcing that is done by dofun is interesting.  It sources the functions that are available in a SAM session.  But it is itself a function.  What sources dofun? The answer is that it is sourced explicitly without the use of a special tool.  I'll show you.  Early in the invocation of SAM this is performed:

    . $sam/dofun
    export -f dofun
    dofun $sam
    dofun $sam_tool

So, you see, dofun "boots" or enables the scheme.  It is what gets the scheme started, therefore it cannot be a part of the scheme.

At this point I have described the solution to problems one through three.  Problem four, the stack, remains.  It is tempting to use Bash to open a new shell as a way of pushing the environment (and thus the command set) onto a stack.  This however, prevents SAM from being especially useful.  I will illustrate.  Let's say that you wanted to write a script that operates inside the shell created by the invocation of SAM.  This script might look like this:

    # do_backup
    # This script "bounds" to example/backup, then it uses
    # the command "gen" to do make a tar file from my root
    # directory.
    bound $sam_distro/example/backup
    gen $env_scratch/root.tar ~/*

It uses the command "gen" which is part of the SAM application.  Here is a listing of gen:

    # example/backup/gen
    # This makes archive $1 containing $2, $3, ...
    tar -cvMf $*

The command gen GENerates a backup file.  The script "do_backup" above uses the gen command in a specific way.  A user may want to do something like this to automate a process he uses repeatedly.  It is simpler to invoke "do_backup" than to enter the two lines that the script contains.

But here is the point:  A script like do_backup won't work if SAM uses Bash to open a new shell when pushing the previous command set onto a stack and changing to the new command set.  If this was done, then the line "bound $sam_distro/example/backup" would make a new shell.  The command gen would be available inside that shell, but that wouldn't help.  We would want to run gen on the next line of the script which wouldn't go until the shell exited.

So instead I wrote two functions called push and pop.  push pushes the current environment onto a special stack that lives in directory $sam_temp_dir.  pop restores the previous environment by using information written to $sam_temp_dir.  The user can run push and pop directly, but there is no need.  The user uses commands bound, hello and bye.  bound does a push before it does its other tasks (actually, it calls hello which calls push).  A partner to hello is bye which invokes pop.

More about SAM
That is essentially the whole SAM system.  I added automatic displaying of the menu after the use of bound or bye.  This helps by showing the user "where" he is after these operations.  I also added code to adjust the prompt so that it shows the directory which contains the current command set.  I included some useful commands in $sam_tool and I packaged SAM with tips and an example directory.  Other documentation is included too.

Also, to make SAM more useful, I have packaged it with a directory called "go".  This directory contains scripts that are normally used when starting SAM.  They allow more than one instance of SAM to run at the same time, either nested or not.  These scripts also handle various useful tasks.  They...

    define variables essential to SAM, such as

    provide a shell for SAM to run inside

    unset any previously defined functions so they will not be inherited by a nested SAM session

    control, in various ways, how SAM runs

And, to make SAM even more useful I have included files I call the "b- files".  These are scripts that invoke SAM for various purposes.  The idea is that the user will copy the b- files to the places where they belong and use them at those locations to invoke SAM in different ways.  For example, the script "begin" in the tips directory can be copied to the user's home directory (~).  It will invoke SAM and provide a useful starting command set.  And it will "add" another another useful command set by use of the add function (defined bye $sam/add.f).  The user will likely want to tailor begin to meet his needs.

4-1-18 update:

I've made some improvements to SAM.  It now installs and runs more easily.  By making use of better scripting I made SAM relocatable.  It now can be installed to and run from a flash drive.  The scripts take care of knowing where they are, and thus do not need to be re-configured when installed (or mounted, in the case of the flash drive) at a new location.

With less need for configuring it was possible to make another improvement:  SAM now installs pre-configured and ready-to-use, and it installs from a single archive.  Download it.  Install it.  Use it.

A Few Closing Comments
I need to mention the system of variables that SAM uses.  I'm talking here about variables that begin "env_".  These are not essential to SAM, but are required for the examples to run on my computer.  For you to get the examples to run on your computer it would be good for you to do two things:  (1) To the extent needed adopt a directory structure like mine, and (2) modify the file $sam_env which defines the variables "env_...".

About this Article and SAM
This article gives an overview of SAM.  For more information see the distribution itself.  You can read more about SAM and learn how to get the distribution by going to this webpage:

This article and SAM were both created by me, Joseph Rosevear.

Copyright (C) 2006, 2007, 2011, 2018 Joseph Rosevear.

© Joseph Rosevear
  |   Source touched: 2022-03-20 16:02:33   |