It is a Shell Scripting Development Kit (ShSDK) that currently supports bash. ShCF helps you develop bash shell scripts in a lightweight manner. This means that you can focus on the core logic of your scripts, NOT on how you use the framework.
ShCF is learnable in an hour or less, provided you already know how to do shell scripting and programming. It even allows you to create a standalone script. See Standalone section.
Install shcf as follows:
~$ basher install github.com/shsdk/shcf
~$ shcf_init.sh
Then read the quick guide except the git clone part which is already done by basher
Create a new shcf-based shell script
~$ git clone https://github.com/shsdk/shcf.git
~$ ./shcf/init.sh
~$ shcf_cli new hello_world
Add basic logic, let's say the greeter() function
~$ shcf_cli lib hello_world greeter
Modify hello_world/lib/greeter.bash.inc to say 'hello world'
Update main script hello_world/bin/hello_world so it calls greeter' TIP: Add it to
autoload_functions' line
To create additional scripts into your project, say `whoami':
~$ shcf_cli bin hello_world whoami
Further usage, help is available. Just run:
~$ shcf_cli help
~$ git clone https://github.com/shsdk/shcf.git
~$ ./init.sh
Platform environment has been set. See below:
SHCF_PLATFORM_ROOT=/home/your_username/shcf/core
At this point, you can use shcf_cli
from any path.
~$ shcf_cli new your_project_dir/hello_world
A successful creation should be something like below:
~$ shcf_cli new your_project_dir/hello_world
template script created in your_project_dir/hello_world/bin/hello_world
Successful creation of your_project_dir/hello_world
~$ chmod u+x ./your_project_dir/bin/hello_world
~ $ ./hello_world
Expect to see the following error:
/home/your_username/your_project_dir/hello_world/lib/autoload_functions.bash.inc: line 26: /home/your_username/your_project_dir/hello_world/lib/rename_function1.bash.inc: No such file or directory
ERROR: Missing required rename_function1
/home/your_username/your_project_dir/hello_world/lib/autoload_functions.bash.inc: line 26: /home/your_username/your_project_dir/hello_world/lib/rename_function2.bash.inc: No such file or directory
ERROR: Missing required rename_function2
/home/your_username/your_project_dir/hello_world/lib/autoload_functions.bash.inc: line 26: /home/your_username/your_project_dir/hello_world/lib/rename_functionX.bash.inc: No such file or directory
ERROR: Missing required rename_functionX
Template View' (see MVC pattern in
INSPIRATION' section below) included 3 functions that where meant to be replaced or removed, hence the error. To fix the problem, go to the Model' (or
lib' directory) and create a function named 'greeter()' (as file greeter.bash.inc) with contents below:
greeter() {
local message=$1
echo "$message!"
}
TIP: Another approach is to create a template file using command shcf_cli lib hello_world greeter
In bin/hello_world
, remove the 3 template functions namely:
rename_function1
rename_function2
rename_functionX
and replace it with greeter
.
Below, the comment block:
## ..............................
## main utility tool starts below
## ..............................
add the line:
greeter "Hello, World"
Of course, save the file.
Rerun, again.
~$ ./hello_world
If you followed the instructions correctly, you should see the greeting:
~$ ./hello_world
Hello, World!
Let's assume you want to create whoami
. Just run the command:
~$ shcf_cli bin hello_world whoami
Same instructions as above, put the logic, make it executable and you're on.
~$ shcf_cli help
- autoad_functions is expected to be defined at the top - autoload within functions is not supported yet
- autoloload_functions' func list must be defined in s specific way
So, with the limitations noted above, if you need a standalone version of an shcf-based script, use the following:
~$ shcf_cli spawn hello_world hello_world
This assumes that your project is named hello_world
and the main script to access it is hello_world
An alternative way to spawn is to simply leave out the script name. It works seemlessly with both single or multiple-script project. So, assuming the same project as earlier presented, syntax now becomes:
~$ shcf_cli spawn hello_world
Optional optimization:
Now, there are parts of the framework that you may not want to use and you want to get rid of it in the resulting
spawned code. An example of this are the constants defined in etc/init.conf
:
declare -r INVALID_VAL=-1
declare -r INVALID=$INVALID_VAL
declare -r FAILED=1
declare -r SUCCESS=0
declare -r FALSE=0
declare -r TRUE=1
you can define a spawn conf for it. There is NO project-wide spawn conf so you need to define one each in
projects/<project_name>/etc/spawn.<script_name>
So for a "hello_world" project with a hello_world
script, it would be in:
projects/hello_world/etc/spawn.hello_world
with content like:
No constants used:
spawn_used_const() {
used_const '__NONE__'
}
Only TRUE or FALSE are used. Send it as string input separated by comma.
spawn_used_const() {
used_const 'TRUE,FALSE'
}
As mentioned, this optimization is optional. Spawn will work without it.
For people who are more comfortable with the usual package installation, SHCF is now available for the two major Linux packages: rpm and deb.
To install rpm, run the following:
curl -s https://packagecloud.io/install/repositories/icasimpan/shcf/script.rpm.sh | sudo bash
For deb installation, run:
~$ curl -s https://packagecloud.io/install/repositories/icasimpan/shcf/script.deb.sh | sudo bash
Package hosting generously provided by Package Cloud. Visit https://packagecloud.io for details.
See docs/howto_contribute.txt
What | Brief Description | Framework Implementation |
---|---|---|
Model | Business logic or the "how". Does the heavy lifting on how specific functionality is carried out. | lib (e.g sqlQuery.bash.inc) |
View | The frontliner, the one that faces the demanding customer, the end-user. | scripts created in bin |
Controller | Mediator/middle-man directing the requests of the demanding customer(via 'View') to corresponding 'model'. | etc/controller.bash.inc |
I've seen a lot of shell scripts and coded a lot myself. As the code grows, so does the maintenance nightmare. Function duplication is one such headache that needs to be addressed.
In this framework, it can be seen in lib/autoload_functions.bash.inc and will be called in script something like
autoload_functions "func1 func2 func3 etc"
The above way to call 'autoload_function' means that functions is directly accessible from 'lib' and NOT in subdirectories.
Autoloading is very flexible and you can re-arrange libraries as you see fit. For example to use sqlQuery function which is stored in 'lib/db/sql/mysql' and 'ishost_up' located in 'lib/box_mgt' you will call 'autoload_function' like
autoload_functions "lib/db/sql/mysql/sqlQuery box_mgt/ishost_up"
In short, auto-loading stays relatively the same. Just prefix a function with the directory where it is stored and no directory name prefix if it is in same level as autoload_functions.bash.inc.
As you may have noticed by now, Auto-loading is very flexible. But my high-level experience of drupal clarified how auto-loading should be done right.
Libraries that is specific to your script MUST be created inside lib/custom
while those that are reusable and comes from external sources (e.g. https://github.com/shsdk/shcf-lib) should be in lib/contrib
.
This concept is not yet enforced in the ShCF but will be in the near future.