SHELLIA(3) | shell library | SHELLIA(3) |
shellia - library for interactive shell scripts
eval "$ia_init"
[[ia_nocheck] | [[ia_stdout|ia_ignore regex] ...]]
ia_add command-sequence
dbg [debug-level [debug-topic ...]] debug-output
ia [-c|-C] [-x]
shellia is a library that allows to run shell scripts silently or interactive and helps to check errors of commands that are combined in steps.
Each function of a shell programm (including the main shell programm) can include a group of steps. A group of steps should always be enclosed between an initializing line eval "$ia_init" and the line with command ia which starts the execution of the steps. Each step is a command-sequence given as string argument to ia_add The command-sequence contained in the string has the same requirements as if it would be given to the shell command eval.
The examples listed below try to show the technical features of shellia in very small examples.
Be aware that the step size in the example listed below is only reasonable to demonstrate shellia features. Please read shellia(7) NOTES, to learn about a reasonable size of interactive steps.
A script using the basic features to print hello world may look like:
01 #!/bin/sh 02 . /usr/share/shellia/ia.interactive 03 eval "$ia_init" 04 ia_add "echo \"hello\"" 05 ia_add "echo \"world\"" 06 ia
In line 02 the shellia library ia.interactive is loaded. Line 03 initializes shellia and is needed before shellia functions can be used. It also consumes all shellia standard options, so that the remaining options will be script-specific-options. Line 04 and 05 are using ia_add to add the echo commands. The execution starts in line 06 with the ia command.
If the script is called without options, it only prints hello and world. If it is called with option -i it will run in interactive mode, as discussed in shellia(1) Basic features.
On debian systems this script may be found at /usr/share/doc/shellia/examples/hello_world.
A script using a function in interactive-mode may look like:
01 . /usr/share/shellia/ia.interactive 02 say_hello() 03 { 04 local name 05 eval "$ia_init" 06 ia_add "name=\"$1\"" 07 ia_add "echo \"hello \$name\"" 08 ia 09 } 10 eval "$ia_init" 11 ia_add "say_hello <-i> -- \"$1\"" 12 ia
Line 01, 10, 12 are equivalent as in the previous example. Line 02, 03, 04, 07 and 09 are normal shell statements, with no additional comments. Line 05 to initialize shellia has to be done in each function. Line 06 sets variable name to $1. Line 08 starts the steps and is needed in all functions. Line 11 uses the special syntax <-i> which allows to switch -i in interactive-mode.
On debian systems this script may be found at /usr/share/doc/shellia/examples/hello_world_fun.
See shellia(1) Interactive-mode to read about using this script.
Before demonstrating how to use the check-mode option -c or -C we first start with the following script, without any check-mode option:
01 . /usr/share/shellia/ia 02 say_hello() 03 { 04 echo "hello $1" 05 echo "end of function say_hello" >&2 06 return 5 07 } 08 eval "$ia_init" 09 ia_add "say_hello \"$1\"" 10 ia
If we run this script we get the following output and exit value:
01 $ ./hello_world_check "shellia user" 02 hello shellia user 03 end of function say_hello 04 $ echo $? 05 5
In the script lines 02 to 07 the function say_hello is defined. To call this function shellia specific syntax is used in script line 08 to 10. Let's assume the function say_hello may represent an external programm, that we have to use, but are not allowed to change it. But we want to change the output presented to the user:
We can get this with check-mode option -c or -C. There is a disccussion about which option to use in shellia(7) When to use check option -c and -C.
To get the wanted behaviour described in previous chapter with check-mode option -c we change script line 10 to:
10 ia -c
and get the following output:
01 $ ./hello_world_check "shellia user" 02 --- output with ERROR from <hello_world_check> running <say_hello "shellia user"> --- 03 e:hello 04 e:end of function say_hello 05 e:exit=5 06 --- (q)uit (r)edo (i)gnore (s)witch interactive --- 07 ?
Output line 01 shows where errors happended. The output lines 03 to 05 start with e: to classify the output as errors. Line 03 is also shown as error, because shellia does not know, that it is the wanted output. Line 04 is what we want to be suppressed. And line 05 now shows every nonzero exit as an error. To make the program to behave as wanted we can add the folloging lines +a, +b and +c before script line 09:
+a ia_stdout "^hello " +b ia_ignore "end of function say_hello$" +c ia_ignore "^exit=5$" 09 ia_add "say_hello \"$1\""
Line +a will display the output we want to see, and line +b and +c will ignore and suppresses what we do not want to see.
A file that starts to fix say_hello with check-mode option -C is provided as example and the usage is explaind in shellia(1). On debian systems this script may be found at /usr/share/doc/shellia/examples/hello_world_error. The changed script line from the example in chapter check-mode is:
10 ia -C
and gives the following output:
01 $ ./hello_world_error "shellia user" 02 --- output with ERROR from <hello_world_error> running <say_hello "shellia user"> --- 03 e:end of function say_hello 04 e:exit=5 05 s:hello --- (q)uit (r)edo (i)gnore (s)witch interactive --- ?
In line 05 s: already classifies the ouput as stdout. To make the program behave as wanted we can add the folloging lines +a and +b before script line 09:
+a ia_ignore "end of function say_hello$" +b ia_ignore "^exit=5$" 09 ia_add "say_hello \"$1\""
The library ia.debug includes functions to add debug-output to a shell script. The script.using.shellia can then be called with a debug-runtime-config to define the debug-level and to select debug-topics. See shellia(1) debug-mode to learn about debug-runtime-config.
A simple script to add debug-output without debug-level or debug-topics is:
01 . /usr/share/shellia/ia 02 say_hello_world() 03 { 04 dbg "say_hello function start" 05 echo "hello world" 06 dbg "say_hello function end" 07 } 08 eval "$ia_init" 09 ia_add "dbg \"main program\"" 10 ia_add say_hello_world 11 ia
Line 01, 08, 10 and 11 are already explained in a previous example. Line 04, 06 and 09 adds debug-output. Because no debug-level is defined the lowest possible value 1 is used.
In this script debug-output can be turned on when the script is started with a runtime debug-level greater or equal to 1.
If you want to use debug-level 3 in the function, you can change the following lines:
04 dbg 3 "say_hello function start" 06 dbg 3 "say_hello function end"
Now a debug-runtime-level of at least 3 is needed to produce output for the changed lines.
Sometimes it is not enough to have debug-levels and you need debug-topics to define which debug-output has to be shown. You can give a free defined debug-topic to each debug-statement line. Normally you should only use a limited number of debug-topics to make things not to complicated.
We change 2 lines to the free invented debug-topics called start and end:
04 dbg 3 start "say_hello function start" 06 dbg 3 end "say_hello function end"
The script now should look like the hello_world_debug script, that on debian systems may be found at /usr/share/doc/shellia/examples/hello_world_debug.
See shellia(1) debug-mode to read about using this script.
The library ia.log includes functions to add logging to a shell script.
In the logfile each line starts with a number of bars. Following lines with the same number of bars, result from the same function, which is used as header.
A simple script with logging called hello_world_log is provided as example. On debian systems it may be found at /usr/share/doc/shellia/examples/hello_world_log. A part of this script is:
01 ia_logfile="$(mktemp)" 02 export ia_logfile 03 . /usr/share/shellia/ia 04 say_hello() 05 { 06 local name 07 eval "$ia_init" 08 ia_add "dbg \"funtion say_hello called with $# arguments\"" 09 ia_add "name=\"$1\"" 10 ia_stdout "^hello" 11 ia_add "echo \"hello \$name\"" 12 ia -c 13 } 14 eval "$ia_init" 15 ia_add "dbg \"main program begin\"" 16 ia_nocheck # do not check the already checked output of next line 17 ia_add "say_hello <-i> -- \"$1\"" 18 ia -c
In line 03 the ia library is loaded, which also loads ia.log. The logging is simply enabled by setting variable ia_logfile in line 01 with the path to the logfile and exporting it in line 02. The new logfile output will be appended to the logfile.
To see 2 levels of logging in the logfile we have a main program and a function in the example. Both use check-mode with ia -c in line 07 and 14 which allows to log checked output. To not double check the function say_hello in the main program line 16 ia_nocheck is added to not check the output of line 17.
The output to the logfile is discussed in shellia(1).
Trace-mode can be enabled with ia -x for a group of steps. When tracemode is enabled, before each step set -x is called and after each stet set +x is called. This way, no shellia internal commands are traced.
A simple script with trace-mode called hello_world_trace is provided as example. On debian systems it may be found at /usr/share/doc/shellia/examples/hello_world_trace. A part of this script is:
01 . /usr/share/shellia/ia 02 write_file() { 03 eval "$ia_init" 04 ia_add "echo \"hello $2\" >$1" 05 ia -c -x 06 } 07 show_file() { 08 eval "$ia_init" 09 ia_stdout "^hello" 10 ia_add "cat $1" 11 ia -c -x 12 } 13 eval "$ia_init" 14 ia_add "file=\"\$(mktemp)\"" 15 ia_add "write_file <-i> -- \"\$file\" \"$1\"" 16 ia_stdout "." 17 ia_add "show_file <-i> -- \"\$file\"" 18 ia_add "rm -f \"\$file\"" 19 ia -c -x
Without trace-mode (without -x in line 05 11 and 19) this script would just print one line starting with hello. The following output is printed when calling
$ /usr/share/doc/shellia/examples/hello_world_trace "shellia user" + mktemp + file=/tmp/tmp.zCDaHg9dFP + echo hello shellia user + write_file -- /tmp/tmp.zCDaHg9dFP shellia user + cat /tmp/tmp.zCDaHg9dFP + show_file -- /tmp/tmp.zCDaHg9dFP hello shellia user + rm -f /tmp/tmp.zCDaHg9dFP
Because log-mode is enabled the following log is written:
|hello_world_trace |+ mktemp |+ file=/tmp/tmp.zCDaHg9dFP ||hello_world_trace/write_file ||+ echo hello shellia user |+ write_file -- /tmp/tmp.zCDaHg9dFP shellia user ||hello_world_trace/show_file ||+ cat /tmp/tmp.zCDaHg9dFP ||s:hello shellia user |+ show_file -- /tmp/tmp.zCDaHg9dFP |s:hello shellia user |+ rm -f /tmp/tmp.zCDaHg9dFP
The log shows, that trace-mode output is included in the log-mode output hierarchie. To get trace-mode output in a logfile, it is important that log-mode and also check-mode is enabled.
Also if no-check is used for a step, this step will not create trace-mode output in the logfile.
Commands or global variables brought by shellia normally start with ia (see NAME in shellia(7)). If ia.debug is used there will also be commands and global variables that start with dbg. But if you already use one or both of this prefixes, you can change them, while loading the library.
The example changes ia to mycmd and dbg to myprnt:
ia_prefix=mycmd dbg_prefix=myprnt . /usr/share/shellia/ia
No all command have to use the new prefix, e.g. ia_add now needs to become mycmd_add.
bernd.schumacher@hpe.com
gpl3
2018-07-26 | 0.1 |