The ConceptBase.cc Shell (CBShell) is a command line client for ConceptBase.cc. It allows to interact with a CBserver via a text-based command shell. Moreover, it can process commands from a script file without further user interaction. The utility can be employed to automate certain activities such as batch-loading a large number of Telos models into a CBserver, or to extract certain answers from a CBserver.
There are two ways to use the CBShell. The first one processes the commands from a script file (batch mode). The second one prompts the user for commands (interactive mode).
cbshell [options] scriptFile [params] cbshell [options]
Command arguments with white space characters have to be enclosed in double quotes (’"’). Command arguments may span multiple lines. Lines starting with ’#’ are comment lines2. If an argument contains a string of the form $PropName, it will be replaced with the value of the corresponding Java property (which may be defined using the -D option of the Java Virtual Machine), if the property is defined. There are a couple of legacy commands that we support for backward compatibility:
The CBShell utility can be used in Unix pipes to extract textual output The CBserver and pass it to subsequent programs as input. To do so, you should start the CBserver with tracemode no and using the showAnswer command of CBShell to specify the elements to be written to standard output. The CBShell script below realizes the extraction of Graphviz [link] specifications from ConceptBase.cc:
# File: myscript connect tellModel ERD-graphviz2 tellModel UniversityModel ask ShowERD[UniversityModel/erd] OBJNAMES default Now showAnswer exit
The complete example is available from the CB-Forum at link. Another resource for CBShell scripts is the list of test scripts at link.
If an argument to a CBShell command spans multiple lines or contains several words separated by blanks, then you have to enclose it in double quotes, being the default argument delimiter. Double quotes are also used for String objects in Telos frames. These have to be escaped like in the following example:
tell " Peter with comment about: \"This is a Telos string\" end "
If many such frames need to be told, the escaping of Telos strings is cumbersome. You can use the single quote as argument delimiter in such cases, making the escaping the double quotes for the Telos string obsolete:
tell ' Peter with comment about: "This is a Telos string" end '
The CBShell can be used to run a script file or in can be used in interactive mode. In the interactive mode, the CBShell shall directly display the response to a command, typically the answer of the ConceptBase server. Some of the shortcuts like ’why’ and ’cd’ are specifically defined to make the interactive mode more effective.
Another feature of the interactive mode is that queries that are represented as a single word can also be asked without the keyword ’ask’ in front of it. CBShell will then ask the query using ’default’ as answer format, i.e. the ConceptBase server will decide in which answer format to use. Below is a sample session of CBShell in interactive mode.
cbshell This is CBShell, the command line interface to ConceptBase.cc [offline]>connect [localhost:4001]>mkdir M1 yes [localhost:4001]>cd M1 M1 [localhost:4001]>tell "Employee in Class" no [localhost:4001]>why Syntax error 1 in line 1, parser message: syntax error, unexpected ENDOFINPUT, expecting END or ENDMIT Syntax error Unable to parse Employee in Class. [localhost:4001]>tell "Employee in Class end" yes [localhost:4001]>tell "bill in Employee end" yes [localhost:4001]>ls Employee bill [localhost:4001]>show bill bill in Employee end [localhost:4001]>1+2 3 [localhost:4001]>stop [offline]>exit
The term 1+2 is an example of a query that is not preceded by the ’ask’ command. Note that such queries may no contain blanks since it would split it into several words. Use quotes in such cases. The prompt [offline] indicates that the CBShell is not yet connected to a CBserver. Once connected, it displays the hostname and port number of the connected CBserver as prompt. The CBserver is started with disabled tracing. The trace messages of the CBserver would otherwise be displayed in the output as well.
A CBShell script can use variables $0 ... $9 inside the script to refer to the positional parameters supplied via the call of cbshell. Assume the following content of the script file:
# File: pascript cbserver -u nonpersistent -t low -port $1 tell "$2 in Class end" ask find_instances[$2/class] OBJNAMES LABEL Now ask find_instances[$3/class] OBJNAMES LABEL Now
and the command line call
cbshell pascript 4321 MyClass Integer
The CBShell interpreter will then replace $1 with 4321, $2 with MyClass, and $3 with Integer. If you supply less parameters than required by the script, it will issue an error message and quit. If the script had started a CBserver, then this CBserver is stopped before quitting. Likewise, if the script had enrolled to an existing CBserver process, it will unenroll before quitting.
The variable $0 is bound to the name of the script file. CBShell uses the Java tokenizer to separate the positional parameters. The tokenizer uses white spaces (blanks, tabs) to separate tokens. Use double quotes if one argument consists of several words, e.g.
cbshell otherscript "MyClass isA Integer end"
An example of a script with positional parameters is provided in the CB-Forum at link. You can also call CBShell scripts within scripts/batch files of the host operating system, see section 7.7.
A CBShell script can be made executable under Unix/Linux and can then be used pretty much like any other shell script. Assume that you have a CBShell script myscript that you want to execute directly from the command line.
As a first step, create a link to the cbshell at a common directory for installed programs:
sudo ln -s $CB_HOME/cbshell /usr/bin/cbshell
where $CB_HOME is replaced by the installation directory of ConceptBase. As a second step include the following comment as the first line of myscript:
#!/usr/bin/cbshell
Then, make the script executable:
chmod u+x myscript
You can then directly call the script by simply typing its name:
myscript
The direct call is equivalent to the call
cbshell ./myscript
CBShell offers the basic commands to interact with a ConceptBase server. However, it lacks control structures such as loops and conditions. It also cannot invoke arbitrary programs. Regular shell scripts such as the Bourne shell of Unix/Linux do provide these capabilities, and thus it is a natural idea to integrate CBShell scripts within regular scripts to accomplish more sophisticated automation tasks.
As a first step, you should make the CBShell script executable and declare in its first line
#!/usr/bin/cbshell -q
This allows to pass parameters that include special characters to the CBShell script. Assume that the CBShell script ascript was declared that way. Then, it can be called in a Bourne shell like:
ascript 'Jet 400' MyClass
The option -q prepares the CBShell to treat parameters with single quotes in a special way. Assume further that ascript has the following content:
#!/usr/bin/cbshell -q # File: ascript ... tell "$1 in $2 end" ...
CBShell will internally expand the quoted parameter ’Jet 400’ to \"Jet 400\" and then execute
tell "\"Jet 400\" in MyClass end"
The resulting frame in ConceptBase shall be
"Jet 400" in MyClass end
Essentially, single quotes of CBShell parameters are converted to double quotes within ConceptBase. An simple example is given in link. A more elaborate example is available in the CB-Forum at link. The main example is in the fileSizeDemo.
Assume you have a program generator that analyzes some input data (e.g from files) and produces output in the form of CBShell commands (tell, ask, etc.). Then, this output can be directly passed to CBShell in a Unix pipe:
generator | cbshell -p
The generator program must take care of generating all required commands, in particular making sure that CBShell is connected to a CBserver. Consider as example generator the script file printfiles4cbshell from the CB-Forum at link:
#!/bin/sh echo "connect localhost 4001" for file in * do if [ -f ${file} ] then fsize=$( stat -c %s ${file}) frame="'${file}' in File with size s: ${fsize} end" echo tell \"\\\"${file}\\\" in File with size s: ${fsize} end\" fi done
It first generates a command to enroll to a CBserver on localhost at port 4001. Then, it forms a frame for each filename in the current directory to tell the file’s size to the CBserver. You can run the script in a terminal to see the output generated by it.
Now, assume that you have started a CBserver on localhost with port number 4001. You should tell at least the following frame to the Cbserver to define the class File to which the above script refers to:
File in Class with attribute size: Integer end
Then execute in a terminal window:
printfiles4cbshell | cbshell -p
It will tell the file size information to the CBserver. At the end, the end of file detection of the CBShell will trigger the CBShell to exit from the CBserver.
It is also possible to continue the pipe to a post-processing program. In this case, the commands sent to CBShell should include ask commands in combination with showAnswer. The following pipe shows the main idea:
generator | cbshell -p | postprocessor
An elaborate example of this usage is in the CB-Forum at link. The example shows how to extract module import statements from program source files, store them in ConceptBase and let ConceptBase produce a graph specification, layed out by GraphViz.