shellia(3)
π NAME π
okay bestie so this one is shellia β a whole library for interactive shell scripts π
β¨ SYNOPSIS β¨
. /usr/share/shellia/ia[.interactive|.check|.debug|]
eval "$ia_init"
[[ia_nocheck [-f]] | [[ia_stdout|ia_ignore regex] ...]]
ia_add command-sequence
dbg [debug-level [debug-topic ...]] debug-output
ia [-c|-C] [-x]
πΈ ENVIRONMENT πΈ
If ia_logfile holds the path to a file that's writeable, then logfile output β exactly as ia sees it β gets appended to that file. no cap π«Ά
π¦ DESCRIPTION π¦
so shellia is a library that lets you run shell scripts either silently or interactively, and it helps you check errors in commands that get combined into steps β¨
Every function of a shell program (and yes, that includes the main shell program itself π
) can contain a group of steps. A group of steps should always be wrapped up between an initializing line eval "$ia_init" and the line with the command ia, which is what actually kicks off execution of the steps. Each step is a command-sequence handed over as a string argument to ia_add. The command-sequence inside that string has the exact same requirements as if you'd handed it to the shell command eval. periodt.
π OPTIONS π
. /usr/share/shellia/ia[.interactive|.check|.debug|]β okay so you've got choices here, and they're all slay in different ways π If you only want the basic interactive features, source. /usr/share/shellia/ia.interactive. If you only want the check library, the one that checks stderr, stdout and the exit-value of steps, source. /usr/share/shellia/ia.check. If you only want the debug library, the one that adds debug-output to a shell script, source. /usr/share/shellia/ia.debug. But the suggested method is to source all of the shellia libraries listed above at once, and you do that with. /usr/share/shellia/iaπia_nocheckβ this one's your get-out-of-checking-free card π Use it when the followingiacommand has turned on check-mode with option[-c|-C]for its group of steps. What it does: it disables the check of stderr and stdout in the next singleia_addstep. Add option-fto it and it'll also disable checking the exit value of that next single step. Oh and also β if a step might exit the script,ia_nocheckis what you use to stop thatERROR: ia premature exit of ...message from showing up πia_stdout regexβ to use this one, the followingiacommand has to be used with option-c. Here regex is a regular expression, defined the waygawk(1)defines them, and it declares which output of the following step (the one defined withia_add) counts as the standard output of that step. Each step can be preceded by any number ofia_stdout regexcommands β¨ Because the user can't suppress output that's been allowed withia_stdoutusing option-s, you should only reach foria_stdoutwhen that output is genuinely meant to be piped into another program. and ngl, regex only needs to handle text without color-control-codes πia_ignore regexβ to use this one, the followingiacommand has to be used with either option-cor-C. Again regex is a regular expression as defined ingawk(1), and it declares which output of the following step (defined withia_add) gets ignored. Each step can be preceded by any number ofia_ignore regexcommands π¦ and yep, regex only needs to handle text without color-control-codes.-cβ give this toiaand every step previously added withia_addgets checked using check-mode option-c(check-mode is right down below bestie π)-Cβ give this toiaand every step previously added withia_addgets checked using check-mode option-C(again, check-mode below π)-xβ give this toiaand every step previously added withia_adduses trace-mode (trace-mode below π)
π USAGE π
The examples below are here to show off the technical features of shellia in teeny tiny little examples π§
Heads up bestie: the step sizes in these examples are only reasonable for demonstrating shellia features. If you want to know what a reasonable size for interactive steps actually looks like, go read shellia(7) NOTES π
β¨ Basic features β¨
A script using the basic features to print hello world may look like this:
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
So, line 02 loads the shellia library ia.interactive π
Line 03 initializes shellia and it's needed before you can use any shellia functions β it also eats up all the shellia standard options, so whatever options are left over become script-specific-options. Lines 04 and 05 use ia_add to add the echo commands. And execution starts in line 06 with the ia command π
If the script gets called with no options at all, it just prints hello and world. Call it with option -i and it runs in interactive mode, like we talk about over in shellia(1) Basic features β¨
On debian systems this script may be found at /usr/share/doc/shellia/examples/hello_world.
π Interactive-mode π
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
Lines 01, 10 and 12 do the same thing as in the previous example. Lines 02, 03, 04, 07 and 09 are just normal shell statements, nothing extra going on there. But line 05 β the shellia initialization β has to happen in each function πΈ Line 06 sets the variable name to $1. Line 08 starts the steps and it's needed in all functions. And line 11 uses the special syntax <-i>, which is what lets you switch -i in interactive-mode π
On debian systems this script may be found at /usr/share/doc/shellia/examples/hello_world_fun.
Go read shellia(1) Interactive-mode to learn about using this script π
π check-mode π
Before we even demonstrate how to use check-mode option -c or -C, let's start with the following script β no check-mode option anywhere:
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
Run that script and we get this 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 script lines 02 to 07 the function say_hello gets defined. To call that function, shellia-specific syntax is used in script lines 08 to 10. Now let's pretend the function say_hello actually represents some external program that we have to use but are not allowed to change. Exceptβ¦ we do want to change the output the user gets to see π
- the output
"end of function say_hello"makes zero sense to the user. We know it's harmless, and we just want it suppressed. - output starting with
"hello"is the good stuff, that's what we want. But any other output β the kind we haven't seen until now β should be displayed as an error. - We want every nonzero exit value shown as an error. Only an exit value of
5seems to be ok and should not be displayed as an error.
We can get all of that with check-mode option -c or -C π
There's a whole discussion about which option to pick over in shellia(7) When to use check option -c and -C.
π check-mode -c π
To get that behaviour we just described using check-mode option -c, we change script line 10 to:
10 ia -c
and we get this 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 the errors happened. Output lines 03 to 05 start with e: to classify that output as errors. Line 03 also shows up as an error, because shellia doesn't know that it's the output we actually wanted π Line 04 is the thing we want suppressed. And line 05 now shows every nonzero exit as an error. To make the program behave how we want, we can add the following 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 displays the output we do want to see, and lines +b and +c ignore and suppress the stuff we don't β¨
β check-mode -C β
A file that starts to fix say_hello using check-mode option -C is provided as an example, and the usage is explained over 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 the check-mode chapter is:
10 ia -C
and it gives this 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 that output as stdout π To make the program behave the way we want, we can add the following 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\""
π§ debug-mode π§
The library ia.debug includes functions that let you 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. Go read shellia(1) debug-mode to learn all about debug-runtime-config π
A simple script that adds debug-output with no debug-level or debug-topics looks like:
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
Lines 01, 08, 10 and 11 have already been explained in a previous example. Lines 04, 06 and 09 add debug-output. And because no debug-level is defined, the lowest possible value, 1, gets used.
In this script, debug-output can be turned on when the script is started with a runtime debug-level greater than or equal to 1 β
If you want to use debug-level 3 in the function, you change these lines:
04 dbg 3 "say_hello function start"
06 dbg 3 "say_hello function end"
And now a debug-runtime-level of at least 3 is needed to produce output for those changed lines π
Sometimes debug-levels alone are just not it, bestie β you need debug-topics to say which debug output actually gets shown. You can slap a freely-defined debug-topic onto every debug-statement line. But fr fr, keep the number of debug-topics small, otherwise things get way too 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, which 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.
log-mode πͺ΅
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 come from the same function, and that function is used as the header. π
A simple script with logging called hello_world_log is provided as an 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 \"function 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 the variable ia_logfile in line 01 to the path of the logfile, and exporting it in line 02. New logfile output gets 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 lets you log checked output. To not double check the function say_hello in the main program, line 16 adds ia_nocheck so the output of line 17 isn't checked.
The output to the logfile is discussed in shellia(1).
trace-mode π
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 get traced.
A simple script with trace-mode called hello_world_trace is provided as an 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 (so 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 hierarchy. To get trace-mode output into a logfile, it's important that log-mode and check-mode are enabled.
Also, if no-check is used for a step, that step will not create trace-mode output in the logfile.
variable in Interactive-mode π§
If you want to let the user see the value of a variable before it's used, with the key press v, you can write $<var> instead of \$var or \${var}.
β¨ high level functions β¨
ia_ssh
ia_add "ia_ssh ssh-options [--fd fd] [--vars vars] destination
shellia-script"
Options:
<ssh-options>β ssh options, described inssh(1)<fd>β the filedescriptors<fd>will be transferred<vars>β the variables<vars>will be provided<destination>β ssh destination, described inssh(1)<shellia-script>β script that can use the transferred filedescriptors and variables
ia_ssh transfers, in addition to the filedescriptors stderr and stdout, the shellia filescriptors $ia_direct_stderr_fd and $ia_log_fd with ssh. It also provides the variables listed in $ia_inherit_vars to the remote shellia-script. π
With $ia_log_fd, the remote shellia-script doesn't need to use its own logfile β the log can just be written to the local logfile. iconic.
Warning: the order of data transferred by filedescriptors may change within a single shellia step. π
PREFIX π
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 these 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
Now the new prefixes have to be used β e.g. ia_add is now mycmd_add.
WARNING π¨
It is not always possible to separate shellia's internal variables from script variables. For this reason, variable names starting with ia_ should not be used in scripts.
SEE ALSO π
shellia(1), shellia(7), gawk(1)
Author
bernd.schumacher@hpe.com
License: GNU General Public License, version 3
Copyright
Bernd Schumacher <bernd.schumacher@hpe.com> (2007-2020)
okay that's a wrap bestie π«Ά this was shellia(3), version 0.1, dated 2020-08-07 β go forth and shellia responsibly, mwah ππΈ
π¦ where this page comes from
- ubuntu resolute: shellia 5.10 Β· GPL-3.0-or-later
- ubuntu stonking: shellia 5.10 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms