Sunday, September 15, 2013

Code Blocks, adding structure to your script

 
Cold Block, I mean Code Blocks
For eight long years, expect-lite was a simple scripting language. Running scripts from the top to the bottom of the file. At the request of an expect-lite user, code blocks were introduced in version 4.2. Code Blocks permit grouping of lines and add structure to your script.

Code Blocks allow you to create multi-line conditionals (if statements), while and foreach loops. Naturally, Code Blocks can be nested. Code blocks start with a square bracket, [, and end with a closing square bracket, ]. Indentation within a Code Block is not required, but makes the script more readable. Let's look at each of these in more detail.

Multi-line Conditional

It has been a limitation for a long time, that expect-lite commands had to be on one line. So the conditional was limited to the following, with the double colon representing else
?if $var > $big ? >do something :: >do something else

However with code blocks, it is now possible to insert multiple lines for the then and else statement, such as:
 ?if $var > $big ? [
  ;red --- Var:$var is out of bounds
  *FAIL
]::[
  ; === incrementing Var:$var
  +$var
]
In the above example, if $var is larger than $big, there is something wrong, tell the user about it using a red coloured comment line, and then mark the script as failed.

The While Loop

The While loop is a simple looping mechanism which has a test or comparison at the top of the loop, and therefore usually needs a couple lines of setup before hand.
$i=0
$max=10
[ $i < $max
   >echo $i
   +$i
]
In the above example, a loop counter variable, $i, is set to zero, and a maximum count, $max, is set before the while loop begins. As mentioned earlier, the code block begins with the open square bracket, and the while loop test is defined, $i < $max. The indented lines print out the value of $i as the while loop progresses, and +$i increments the value of $i. Lastly, the lone close square bracket on a separate line, indicates the end of the Code Block, and hence, the while loop.

The Foreach Loop

The foreach loop is another looping mechanism where the items to be iterated over are known beforehand. For example, the script writer may want to iterate over the planet names. In each iteration of the loop, the variable $planet will be assigned a value in the list of planets.
[ $planet=mercury venus earth mars  jupiter  saturn  uranus    neptune
  >ping6 c1 $planet
] 
Of course, until the internet is extended to the interplanetary-internet, using IPv6 naturally, you may not receive an answer to the ping, but you get the idea. 

Foreach loops have the limitation in expect-lite, that the items in the list must be space delimited. As you can see in the example above, multiple spaces are allowed. And if your list as something else as a delimiter, such as a comma, there is an expect-lite feature called string math to help.
$planets=mercury,venus,earth,mars,jupiter,saturn,uranus,neptune
; === use string math /search/replace/ to convert commas to spaces
=$planets /,/ / 

 Please look at the man page, or online documentation for more information on string math.

Keeping it Simple

Code Blocks do add a bit of complexity to the script, but the added structure will bring more power, and clarity to your scripts, all the while keeping it simple.




Saturday, July 6, 2013

Just like being there

Remote control was what expect-lite was born to do. In the early days of expect-lite, there was a need to log into an embedded linux machine and run some tests. There was also a need to log into different remote hosts with same script, so switching which remote host to test had to be easy, as easy as putting it on the command line.

Of course there are several different methods to access a remote host, and to that end, expect-lite supports telnet, ssh, both will username and password options, and a third method, ssh with keys, which requires no password, but the keys have to be set up ahead of time. These methods are selected by setting an environment variable EL_CONNECT_METHOD.

Over the years of using expect-lite I have found while handy to connect to the remote embedded system, it isn't always the best method. Often embedded systems don't have a full linux (or other OS) on them, after all it is by its nature a small system. So I have found that logging into my desktop linux system (aka localhost) provides a rich full set of utilities, and the script can then log into the embedded system (using a variable $IP to control which embedded system).
./myscript IP=192.168.1.10

My .expect-literc which creates my environment  looks like this:
export EL_REMOTE_HOST=localhost
export EL_CONNECT_METHOD=ssh_key


Of course, I have set up ssh keys to my localhost, allowing expect-lite to login without using a password. This is easily done by using the configuration-only option of the installation script, install.sh, in /usr/share/doc/expect-lite (if you installed using the deb or rpm file), or in expect-lite.proj directory where ever you untarred the tarball.
$ cd <install.sh directory>
$ ./install.sh -c
=======================================
Installing expect-lite version "4.6.0"
1,2,3)  ===================
        Configuration Only selected, skipping install steps 1,2,3
...


Fine print: the install script really only sets up the environment for bash shell (or sh, or ksh). It does not set up csh (or similar shells). I use bash, and that is the default shell for most distros today. expect-lite can and does work with csh, but you will need to adjust the environment using csh syntax

Before using the environment created by install.sh it is necessary to either a) relogin, or b) source your ~/.bashrc from the shell. Only then will the new environment take effect.

With this environment, expect-lite will log into the localhost using ssh keys (yellow arrow in diagram above), and then the script will log into the remote host, such as an embedded system (the blue arrow). For additional flexibility I use the *FORK command to create another session to the localhost linux system.
*FORK linux
And switching back to the remote host with:
*FORK default
Now the script has access to the rich set of linux utilities, and the embedded system under test.

Of course, you don't have to use this method. expect-lite supports connecting directly to the remote host as I stated earlier. Either way works well, and for the script, it is just like being there.


Tuesday, February 19, 2013

To quote or not to quote

Quotes, really useful to convey a meaning or sentiment. When used in traditional software languages, quotes depict a string of characters. However, the mantra of expect-lite is keeping it simple, and quotes are not required.

In fact, quotes aren't even optional, and can cause problems when trying to quote strings. Take the following example:
$abc="hello world"
$def=hello world
The two variables are NOT equal. Expect-lite will store the quote characters as part of $abc.

Traditionally using quotes allows the programmer to encompass all characters between the quotes, but this becomes a problem when the quote character is part of the string to be stored. But then a whole system of escaping characters needs to be introduced.

Expect-lite eliminates all that complexity by storing everything after the equal sign, spaces, quotes, tabs, everything. Even more equals signs, such as below:
$equation=5 + 2 = 7

This feature is handy when assigning non-printable characters such as tab. It is possible to store the tab character by pressing the tab key after the equals sign:
$tab=

The $tab can then be used to test tab completion of a command line, such as when using the bash shell, and pressing tab twice to see possible file names:
>ls /etc/rc$tab$tab
<rc3.d

Quotes are not even required when using while loops or if statements. Expect-lite will just do the right thing. For example earlier we set the variable $def, and the following will totally work:
?if $def == hello world ? >hello back!

So save the quotes for Shakespeare, and remember expect-lite is about keeping it it simple.




Sunday, January 20, 2013

Turning Eight

Turning Eight
It started on 19 January 2005. Hard to believe it has been eight years since I first took up the keyboard and started writing expect-lite.

Of course, it was a few weeks before expect-lite could actually do anything useful. But the idea of keeping it simple, and sending > and expecting < was there.

In software development, as a rule, major versions don't have to be compatible with previous versions, but expect-lite has kept backward compatibility since those early days of 2005. It has been a long-standing goal to be able to run a script written years ago on the latest version of expect-lite.
  • 1.x - Basic functionality
  • 2.x - Added Dynamic Variables, Better Var parsing, Embedded Expect
    • version 2.4.0, expect-lite goes open source!
  • 3.x - Looping using %labels,  multiple sessions (*FORK), break points (*INTERACT), Colour
  • 4.x - Integrated Debugger with ^\, Integrated as a TCL library, Code Blocks [ ], User defined script help using ;;; and Logging to a file (*LOG)
Fast forward 8 years, and almost 10,000 downloads later, and expect-lite is still going strong. Many of the features added are a direct result of users' comments. For example, built in logging to a file using *LOG, has has been on the request list for a while, but I do listen, and now it is in the latest release.

Thank you for all of those comments and feature requests over the years, I look forward to more.

Craig...
[author and maintainer of expect-lite]