.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "SHELLIA" 3 "2020-08-07" "0.1" "shell library" .SH NAME shellia \- library for interactive shell scripts .SH SYNOPSIS .INDENT 0.0 .INDENT 3.5 \fB\&. /usr/share/shellia/ia[.interactive|.check|.debug|]\fP .sp \fBeval \(dq$ia_init\(dq\fP .sp [[\fBia_nocheck\fP [\fB\-f\fP]] | [[\fBia_stdout|ia_ignore\fP \fIregex\fP] ...]] .sp \fBia_add\fP \fIcommand\-sequence\fP .sp \fBdbg\fP [\fBdebug\-level\fP [\fBdebug\-topic\fP ...]] \fBdebug\-output\fP .sp \fBia\fP [\fB\-c|\-C\fP] [\fB\-x\fP] .UNINDENT .UNINDENT .SH ENVIRONMENT .INDENT 0.0 .INDENT 3.5 If \fBia_logfile\fP contains the path to a writeable file, logfile output as seen by \fBia\fP is appended to that file. .UNINDENT .UNINDENT .SH DESCRIPTION .sp \fBshellia\fP is a library that allows to run shell scripts silently or interactive and helps to check errors of commands that are combined in \fBsteps\fP\&. .sp Each function of a shell programm (including the main shell programm) can include a group of \fBsteps\fP\&. A group of \fBsteps\fP should always be enclosed between an initializing line \fBeval \(dq$ia_init\(dq\fP and the line with command \fBia\fP which starts the execution of the \fBsteps\fP\&. Each \fBstep\fP is a \fIcommand\-sequence\fP given as string argument to \fBia_add\fP The \fIcommand\-sequence\fP contained in the string has the same requirements as if it would be given to the shell command \fIeval\fP\&. .SH OPTIONS .INDENT 0.0 .TP .B \fB\&. /usr/share/shellia/ia[.interactive|.check|.debug|]\fP To only load the \fBshellia\fP interactive library for basic interactive features use \fI\&. /usr/share/shellia/ia.interactive\fP\&. To only load shellia check library to check stderr, stdout and exit\-value of \fBsteps\fP use \fI\&. /usr/share/shellia/ia.check\fP\&. TO only load the shellia debug library, to add \fBdebug\-output\fP to a shell script use \fI\&. /usr/share/shellia/ia.debug\fP\&. To source all shellia libraries listed above is the suggested method and can be done with \fI\&. /usr/share/shellia/ia\fP\&. .TP .B \fBia_nocheck\fP This command can be used, if the following \fBia\fP command has enabled \fBcheck\-mode\fP with option [\fB\-c|\-C\fP] for its group of \fBsteps\fP\&. This will disable the check of \fIstderr\fP and \fIstdout\fP in the next single \fBia_add\fP \fBstep\fP\&. With opiton \fB\-f\fP added, it will also disable checking the exit value of the next single step. Also if a \fBstep\fP may exit the script, \fBia_nocheck\fP can be used to prevent the message \fIERROR: ia premature exit of ...\fP\&. .TP .B \fBia_stdout\fP \fIregex\fP to use this command, the following \fBia\fP command has to be used with option \fB\-c\fP\&. \fIregex\fP is a regualar expressions as defined in gawk(1), to define which output of the following \fBstep\fP defined with \fBia_add\fP will be standard output of the \fBstep\fP\&. Each \fBstep\fP can be preceded with any number of \fBia_stdout\fP \fIregex\fP commands. Because the user can not suppress output allowed with \fBia_stodut\fP with the option \fB\-s\fP, \fBia_stdout\fP should only be used, if the output is intendet to be piped to another programm. \fIregex\fP only needs to handle text without color\-control\-codes. .TP .B \fBia_ignore\fP \fIregex\fP to use this command, the following \fBia\fP command has to be used with either option \fB\-c\fP or \fB\-C\fP\&. \fIregex\fP is a regualar expressions as defined in gawk(1), to define which output of the following \fBstep\fP defined with \fBia_add\fP will be ignored. Each \fBstep\fP can be preceded with any number of \fBia_ignore\fP \fIregex\fP commands. \fIregex\fP only needs to handle text without color\-control\-codes. .TP .B \fB\-c\fP if this option is given to \fBia\fP all \fBsteps\fP previous added with \fBia_add\fP will be checked with \fBcheck\-mode\fP option \fB\-c\fP (see \fBcheck\-mode\fP below) .TP .B \fB\-C\fP if this option is given to \fBia\fP all \fBsteps\fP previous added with \fBia_add\fP will be checked with \fBcheck\-mode\fP option \fB\-C\fP\&. (see \fBcheck\-mode\fP below) .TP .B \fB\-x\fP if this option is given to \fBia\fP all \fBsteps\fP previous added with \fBia_add\fP will use \fBtrace\-mode\fP\&. (see \fBtrace\-mode\fP below) .UNINDENT .SH USAGE .sp The examples listed below try to show the technical features of \fBshellia\fP in very small examples. .sp Be aware that the \fBstep\fP size in the example listed below is only reasonable to demonstrate shellia features. Please read shellia(7) \fBNOTES\fP, to learn about a reasonable size of interactive \fBsteps\fP\&. .SS Basic features .sp A script using the basic features to print \fIhello world\fP may look like: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 #!/bin/sh 02 . /usr/share/shellia/ia.interactive 03 eval \(dq$ia_init\(dq 04 ia_add \(dqecho \e\(dqhello\e\(dq\(dq 05 ia_add \(dqecho \e\(dqworld\e\(dq\(dq 06 ia .EE .UNINDENT .UNINDENT .sp In line 02 the \fBshellia\fP library \fBia.interactive\fP is loaded. Line 03 initializes \fBshellia\fP and is needed before \fBshellia\fP functions can be used. It also consumes all shellia standard options, so that the remaining options will be \fIscript\-specific\-options\fP\&. Line 04 and 05 are using \fBia_add\fP to add the \fIecho\fP commands. The execution starts in line 06 with the \fBia\fP command. .sp If the script is called without options, it only prints \fIhello\fP and \fIworld\fP\&. If it is called with option \fB\-i\fP it will run in interactive mode, as discussed in shellia(1) \fBBasic features\fP\&. .sp On \fBdebian\fP systems this script may be found at \fI/usr/share/doc/shellia/examples/hello_world\fP\&. .SS Interactive\-mode .sp A script using a function in \fBinteractive\-mode\fP may look like: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 . /usr/share/shellia/ia.interactive 02 say_hello() 03 { 04 local name 05 eval \(dq$ia_init\(dq 06 ia_add \(dqname=\e\(dq$1\e\(dq\(dq 07 ia_add \(dqecho \e\(dqhello \e$name\e\(dq\(dq 08 ia 09 } 10 eval \(dq$ia_init\(dq 11 ia_add \(dqsay_hello <\-i> \-\- \e\(dq$1\e\(dq\(dq 12 ia .EE .UNINDENT .UNINDENT .sp 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 \fBshellia\fP has to be done in each function. Line 06 sets variable name to $1. Line 08 starts the \fBsteps\fP and is needed in all functions. Line 11 uses the special syntax \fI<\-i>\fP which allows to switch \fB\-i\fP in \fBinteractive\-mode\fP\&. .sp On \fBdebian\fP systems this script may be found at \fI/usr/share/doc/shellia/examples/hello_world_fun\fP\&. .sp See shellia(1) \fBInteractive\-mode\fP to read about using this script. .SS check\-mode .sp Before demonstrating how to use the \fBcheck\-mode\fP option \fB\-c\fP or \fB\-C\fP we first start with the following script, without any \fBcheck\-mode\fP option: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 . /usr/share/shellia/ia 02 say_hello() 03 { 04 echo \(dqhello $1\(dq 05 echo \(dqend of function say_hello\(dq >&2 06 return 5 07 } 08 eval \(dq$ia_init\(dq 09 ia_add \(dqsay_hello \e\(dq$1\e\(dq\(dq 10 ia .EE .UNINDENT .UNINDENT .sp If we run this script we get the following output and exit value: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 $ ./hello_world_check \(dqshellia user\(dq 02 hello shellia user 03 end of function say_hello 04 $ echo $? 05 5 .EE .UNINDENT .UNINDENT .sp In the script lines 02 to 07 the function \fIsay_hello\fP is defined. To call this function \fBshellia\fP specific syntax is used in script line 08 to 10. Let\(aqs assume the function \fIsay_hello\fP 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: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 the output \(dqend of function say_hello\(dq makes no sense for the user. We know it is harmless, and we just want to suppress it. .IP \(bu 2 output starting with \(dqhello\(dq is what we want. But any other output, that we may not have seen until now, should be displayed as error. .IP \(bu 2 We want to see every nonzero exit value as an error. Only an exit value of 5 seems to be ok and should not be displayed as error. .UNINDENT .UNINDENT .UNINDENT .sp We can get this with \fBcheck\-mode\fP option \fB\-c\fP or \fB\-C\fP\&. There is a disccussion about which option to use in shellia(7) \fBWhen to use check option \-c and \-C\fP\&. .SS check\-mode \-c .sp To get the wanted behaviour described in previous chapter with \fBcheck\-mode\fP option \fB\-c\fP we change script line 10 to: .INDENT 0.0 .INDENT 3.5 .sp .EX 10 ia \-c .EE .UNINDENT .UNINDENT .sp and get the following output: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 $ ./hello_world_check \(dqshellia user\(dq 02 \-\-\- output with ERROR from running \-\-\- 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 ? .EE .UNINDENT .UNINDENT .sp Output line 01 shows where errors happended. The output lines 03 to 05 start with \fIe:\fP 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: .INDENT 0.0 .INDENT 3.5 .sp .EX +a ia_stdout \(dq^hello \(dq +b ia_ignore \(dqend of function say_hello$\(dq +c ia_ignore \(dq^exit=5$\(dq 09 ia_add \(dqsay_hello \e\(dq$1\e\(dq\(dq .EE .UNINDENT .UNINDENT .sp 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. .SS check\-mode \-C .sp A file that starts to fix \fIsay_hello\fP with \fBcheck\-mode\fP option \fB\-C\fP is provided as example and the usage is explaind in shellia(1). On \fBdebian\fP systems this script may be found at \fI/usr/share/doc/shellia/examples/hello_world_error\fP\&. The changed script line from the example in chapter \fBcheck\-mode\fP is: .INDENT 0.0 .INDENT 3.5 .sp .EX 10 ia \-C .EE .UNINDENT .UNINDENT .sp and gives the following output: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 $ ./hello_world_error \(dqshellia user\(dq 02 \-\-\- output with ERROR from running \-\-\- 03 e:end of function say_hello 04 e:exit=5 05 s:hello \-\-\- (q)uit (r)edo (i)gnore (s)witch interactive \-\-\- ? .EE .UNINDENT .UNINDENT .sp In line 05 \fIs:\fP already classifies the ouput as \fIstdout\fP\&. To make the program behave as wanted we can add the folloging lines +a and +b before script line 09: .INDENT 0.0 .INDENT 3.5 .sp .EX +a ia_ignore \(dqend of function say_hello$\(dq +b ia_ignore \(dq^exit=5$\(dq 09 ia_add \(dqsay_hello \e\(dq$1\e\(dq\(dq .EE .UNINDENT .UNINDENT .SS debug\-mode .sp The library \fIia.debug\fP includes functions to add \fBdebug\-output\fP to a shell script. The \fIscript.using.shellia\fP can then be called with a \fIdebug\-runtime\-config\fP to define the \fBdebug\-level\fP and to select \fBdebug\-topics\fP\&. See shellia(1) \fBdebug\-mode\fP to learn about \fIdebug\-runtime\-config\fP\&. .sp A simple script to add \fBdebug\-output\fP without \fBdebug\-level\fP or \fBdebug\-topics\fP is: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 . /usr/share/shellia/ia 02 say_hello_world() 03 { 04 dbg \(dqsay_hello function start\(dq 05 echo \(dqhello world\(dq 06 dbg \(dqsay_hello function end\(dq 07 } 08 eval \(dq$ia_init\(dq 09 ia_add \(dqdbg \e\(dqmain program\e\(dq\(dq 10 ia_add say_hello_world 11 ia .EE .UNINDENT .UNINDENT .sp Line 01, 08, 10 and 11 are already explained in a previous example. Line 04, 06 and 09 adds \fBdebug\-output\fP\&. Because no \fBdebug\-level\fP is defined the lowest possible value \fI1\fP is used. .sp In this script \fBdebug\-output\fP can be turned on when the script is started with a runtime \fBdebug\-level\fP greater or equal to \fI1\fP\&. .sp If you want to use \fBdebug\-level\fP \fI3\fP in the function, you can change the following lines: .INDENT 0.0 .INDENT 3.5 .sp .EX 04 dbg 3 \(dqsay_hello function start\(dq 06 dbg 3 \(dqsay_hello function end\(dq .EE .UNINDENT .UNINDENT .sp Now a \fBdebug\-runtime\-level\fP of at least 3 is needed to produce output for the changed lines. .sp Sometimes it is not enough to have \fBdebug\-levels\fP and you need \fBdebug\-topics\fP to define which \fBdebug\-output\fP has to be shown. You can give a free defined \fBdebug\-topic\fP to each \fIdebug\-statement\fP line. Normally you should only use a limited number of \fBdebug\-topics\fP to make things not to complicated. .sp We change 2 lines to the free invented \fBdebug\-topics\fP called \fIstart\fP and \fIend\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX 04 dbg 3 start \(dqsay_hello function start\(dq 06 dbg 3 end \(dqsay_hello function end\(dq .EE .UNINDENT .UNINDENT .sp The script now should look like the \fIhello_world_debug\fP script, that on \fBdebian\fP systems may be found at \fI/usr/share/doc/shellia/examples/hello_world_debug\fP\&. .sp See shellia(1) \fBdebug\-mode\fP to read about using this script. .SS log\-mode .sp The library \fIia.log\fP includes functions to add logging to a shell script. .sp 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. .sp A simple script with logging called \fIhello_world_log\fP is provided as example. On \fBdebian\fP systems it may be found at \fI/usr/share/doc/shellia/examples/hello_world_log\fP\&. A part of this script is: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 ia_logfile=\(dq$(mktemp)\(dq 02 export ia_logfile 03 . /usr/share/shellia/ia 04 say_hello() 05 { 06 local name 07 eval \(dq$ia_init\(dq 08 ia_add \(dqdbg \e\(dqfunction say_hello called with $# arguments\e\(dq\(dq 09 ia_add \(dqname=\e\(dq$1\e\(dq\(dq 10 ia_stdout \(dq^hello\(dq 11 ia_add \(dqecho \e\(dqhello \e$name\e\(dq\(dq 12 ia \-c 13 } 14 eval \(dq$ia_init\(dq 15 ia_add \(dqdbg \e\(dqmain program begin\e\(dq\(dq 16 ia_nocheck # do not check the already checked output of next line 17 ia_add \(dqsay_hello <\-i> \-\- \e\(dq$1\e\(dq\(dq 18 ia \-c .EE .UNINDENT .UNINDENT .sp In line 03 the \fBia\fP library is loaded, which also loads \fBia.log\fP\&. The logging is simply enabled by setting variable \fBia_logfile\fP 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. .sp To see 2 levels of logging in the logfile we have a main program and a function in the example. Both use \fBcheck\-mode\fP with \fIia \-c\fP in line 07 and 14 which allows to log checked output. To not double check the function \fIsay_hello\fP in the main program line 16 \fIia_nocheck\fP is added to not check the output of line 17. .sp The output to the logfile is discussed in shellia(1). .SS trace\-mode .sp \fBTrace\-mode\fP can be enabled with \fIia \-x\fP for a group of \fBsteps\fP\&. When tracemode is enabled, before each \fBstep\fP \fIset \-x\fP is called and after each stet \fIset +x\fP is called. This way, no \fBshellia\fP internal commands are traced. .sp A simple script with \fBtrace\-mode\fP called \fIhello_world_trace\fP is provided as example. On \fBdebian\fP systems it may be found at \fI/usr/share/doc/shellia/examples/hello_world_trace\fP\&. A part of this script is: .INDENT 0.0 .INDENT 3.5 .sp .EX 01 . /usr/share/shellia/ia 02 write_file() { 03 eval \(dq$ia_init\(dq 04 ia_add \(dqecho \e\(dqhello $2\e\(dq >$1\(dq 05 ia \-c \-x 06 } 07 show_file() { 08 eval \(dq$ia_init\(dq 09 ia_stdout \(dq^hello\(dq 10 ia_add \(dqcat $1\(dq 11 ia \-c \-x 12 } 13 eval \(dq$ia_init\(dq 14 ia_add \(dqfile=\e\(dq\e$(mktemp)\e\(dq\(dq 15 ia_add \(dqwrite_file <\-i> \-\- \e\(dq\e$file\e\(dq \e\(dq$1\e\(dq\(dq 16 ia_stdout \(dq.\(dq 17 ia_add \(dqshow_file <\-i> \-\- \e\(dq\e$file\e\(dq\(dq 18 ia_add \(dqrm \-f \e\(dq\e$file\e\(dq\(dq 19 ia \-c \-x .EE .UNINDENT .UNINDENT .sp Without \fBtrace\-mode\fP (without \fB\-x\fP in line 05 11 and 19) this script would just print one line starting with \fIhello\fP\&. The following output is printed when calling .INDENT 0.0 .INDENT 3.5 .sp .EX $ /usr/share/doc/shellia/examples/hello_world_trace \(dqshellia user\(dq + 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 .EE .UNINDENT .UNINDENT .sp Because \fBlog\-mode\fP is enabled the following log is written: .INDENT 0.0 .INDENT 3.5 .sp .EX |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 .EE .UNINDENT .UNINDENT .sp The log shows, that \fBtrace\-mode\fP output is included in the \fBlog\-mode\fP output hierarchie. To get \fBtrace\-mode\fP output in a logfile, it is important that \fBlog\-mode\fP and also \fBcheck\-mode\fP is enabled. .sp Also if \fBno\-check\fP is used for a \fBstep\fP, this step will not create \fBtrace\-mode\fP output in the logfile. .SS variable in Interactive\-mode .sp If you want to enable the user to see the value of a variable, before it is used, with key press \fBv\fP, you can write \fI$\fP instead of \fI\e$var\fP or \fI\e${var}\fP\&. .SH HIGH LEVEL FUNCTIONS .SS ia_ssh .INDENT 0.0 .INDENT 3.5 \fBia_add\fP \(dq\fBia_ssh\fP \fIssh\-options\fP [\fB\-\-fd\fP \fIfd\fP] [\fB\-\-vars\fP \fIvars\fP] \fIdestination\fP \fIshellia\-script\fP\(dq .UNINDENT .UNINDENT .sp Options: .INDENT 0.0 .INDENT 3.5 .sp .EX ssh options described in ssh(1) the filedescriptors will be transfered the variables will be provided ssh destination described in ssh(1) script that can use the transferred filedescriptors and variables .EE .UNINDENT .UNINDENT .sp \fBia_ssh\fP transfers additional to the filedescriptors \fBstderr\fP and \fBstdout\fP the shellia filescriptors \fB$ia_direct_stderr_fd\fP and \fB$ia_log_fd\fP with \fBssh\fP\&. Also the variables listed in \fB$ia_inherit_vars\fP are provided to the remote \fIshellia\-script\fP\&. .sp With \fB$ia_log_fd\fP the remote \fIshellia\-script\fP does not need to use an own logfile and the log can be written to the local logfile. .sp Warning: The order of data transferred by filedescriptors may change within a single shellia step. .SH PREFIX .sp Commands or global variables brought by \fBshellia\fP normally start with \fBia\fP (see \fBNAME\fP in shellia(7)). If \fBia.debug\fP is used there will also be commands and global variables that start with \fIdbg\fP\&. But if you already use one or both of this prefixes, you can change them, while loading the library. .sp The example changes \fBia\fP to \fImycmd\fP and \fIdbg\fP to \fImyprnt\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX ia_prefix=mycmd dbg_prefix=myprnt \&. /usr/share/shellia/ia .EE .UNINDENT .UNINDENT .sp Now the new prefixes have to be used, e.g. \fIia_add\fP is now \fImycmd_add\fP\&. .SH WARNING .sp It is not always possible to separate \fBsellia\fP\(aqs internal variables from script variables. For this reason variable names starting with \fBia_\fP should not be used in scripts. .SH SEE ALSO .sp shellia(1), shellia(7), gawk(1) .SH AUTHOR bernd.schumacher@hpe.com License: GNU General Public License, version 3 .SH COPYRIGHT Bernd Schumacher (2007-2020) .\" Generated by docutils manpage writer. .