Skip to main content

Shell Expressions

At the core of any Scrut test case is a command line that is being tested. It can be a single command, a sequence of commands spanning multiple lines or anything else could possibly be written or pasted on the command line and executed. This command line is called a shell expression.

All of the following are valid shell expressions:

Terminal
$ date
$ echo Hello World
$ date && echo Hello World
$ function foo() { echo Hello World; }; foo
$ cat foo | grep bar | wc -l
$ function foo() { echo Hello World; }; \
foo | \
grep Hello | \
wc -l

The rule of thumb is: If you can paste and excecute it in the shell, then it is a valid shell expression.

Constraints

For the sake of understanding assume that each shell expression is written to a file and this file is then executed with bash. Like so:

Terminal
$ echo 'echo My shell expression' > shell-expression.sh
$ bash shell-expression.sh
My shell expression
note

Learn about the how execution works in Reference > Behavior > Execution Model.

This behavior implies some limits / constraints on what you can expect from the result:

Returned Exit Code

Consider the following shell expression:

$ false ; true

This executes the command false and then executes the command true. They are both separated by a ;, which makes them individual commands from the bash perspective. If you would have a bash script file with these contents and would execute it, then you would see the exit code 0:

Terminal
$ echo 'false ; true' > shell-expression.sh
$ bash shell-expression.sh
$ echo $?
0

That means the exit code of false (which is 1) is not surfaced, because the shell script itself continues to the next command (true). The returned exit code is simply the exit code of the last command in the shell script.

If this behavior is not desired (it may be), then you could use the && operator instead of ;:

Terminal
$ echo 'false && true' > shell-expression.sh
$ bash shell-expression.sh
$ echo $?
1

Alternatively, as these are bash scripts, you can also use the set -e directive to make the shell script exit on the first non-zero exit code:

Terminal
$ echo 'set -e ; false ; true' > shell-expression.sh
$ bash shell-expression.sh
$ echo $?
1
warning

Due to the different execution model of Cram using set -e will terminate not only the test case, but all test cases in the same test document. Do not use it.

Detached Processes

When Scrut runs a shell expression it will wait for the execution to finish, so that it can gather the exit code and the output and validate it as defined by the test case.

However, if the shell expression detaches from the shell, or spawns processes that are detached (or both) then Scrut will not wait for them. Scrut will not manage their lifetime at all.

tip

If you need to test a server/client scenario, where first a server must be started and before the CLI test cases can execute then have a look at the detached/wait configuration directives.