> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/sast-and-sca/ocular/modes.md).

# Interactive Shell

Ocular provides an interactive shell for code analysis, much like an operating system shell. We base this shell on the popular Scala shell [Ammonite](http://ammonite.io/#Features). In summary, the shell offers the following major features:

* Tab-completion
* GNU readline support for line editing
* JSON output
* Pipe operators
* Inline code browsing with a pager
* Dynamic library import

## Launching the Interactive Shell <a href="#launching-the-interactive-shell" id="launching-the-interactive-shell"></a>

The shell can be started by issuing the following command:

```
sl ocular
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

## Basic Keyboard Commands <a href="#basic-keyboard-commands" id="basic-keyboard-commands"></a>

The Ocular underlying shell is essentially an interactive Scala shell that supports the following keyboard commands:

| **Command**     | **Description**                                                                 |
| --------------- | ------------------------------------------------------------------------------- |
| CTRL-c          | Cancels current operation/clears shell. Does *not* quit Ocular                  |
| CTRL-d          | Quits Ocular (shell must be clear)                                              |
| TAB             | Autocomplete                                                                    |
| UP              | Moves through command history                                                   |
| CTRL-LEFT/RIGHT | Step through commands word-by-word (instead of character-by-character)          |
| CTRL-r          | Searches command history. Use CTRL-r (or UP/DOWN) to cycle through your matches |

## Exporting Results with Pipe Operators and `toJson` <a href="#exporting-results-with-pipe-operators-and-tojson" id="exporting-results-with-pipe-operators-and-tojson"></a>

The execution directive (see [Traversal Basics](/sast-and-sca/ocular/traversal-basics.md)) `toJson` can be used at the end of queries in order to convert results into the JSON format. This feature can be combined with the shell's pipe operators to write results out to the file system. For example,

```
cpg.method.toJson |> "/tmp/foo.json"
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

writes all methods nodes into the file `/tmp/foo.json`.

## Inline Code Browsing <a href="#inline-code-browsing" id="inline-code-browsing"></a>

For an increasing number of languages, the Ocular shell allows you to read code associated with query results directly on the shell. For example, to review all calls to `memcpy`, you can issue:

```
ocular> cpg.method.name("memcpy").callIn.code.l

res5: List[String] = List(
  "memcpy(buf, first, first_len)",
  "memcpy(buf + first_len, second, second_len)",
  "memcpy(buf, first, first_len)",
  "memcpy(buf + first_len, second, second_len)",
  "memcpy(buf + first_len, second, second_len)",
  "memcpy(buf, first, first_len)"
)
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

You can also pipe the result list into a pager as follows:

```
ocular> browse(cpg.method.name("memcpy").callIn.code.l)
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

To study the context in which a result occurs, you can use the .dump method, which will dump the enclosing function’s code for each finding, and point you to the finding via an arrow:

```
ocular> cpg.method.name("memcpy").callIn.dump

int main() {
  unsigned int first_len = UINT_MAX - 256;
  unsigned int second_len = 256;
  unsigned int buf_len = 256;

  char first[first_len], second[second_len], buf[buf_len];
  int new_len = (first_len+second_len); // <- IDB (negative)

  if(new_len <= 256) {
    memcpy(buf, first, first_len);
        memcpy(buf + first_len, second, second_len); /* <=== */
  }
}

...
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

You can use this feature together with browse to read code in the pager. Finally, if you want to read the code in your editor of choice, just dump it to a file:

```
cpg.method.name("memcpy").callIn.dumpRaw |> "/tmp/foo.c"
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

We use `dumpRaw` here to skip syntax highlighting, as your editor will most likely do that for you.

![](/files/mlZo7QhbBaWAQlpvEVi9)note

Please make sure [source-highlight](https://www.gnu.org/software/src-highlite/) is installed for the `.dump` feature to work.

### Dynamically Importing Additional Scripts <a href="#dynamically-importing-additional-scripts" id="dynamically-importing-additional-scripts"></a>

You can dynamically load additional scripts at any time.

As an example, let's assume there's a file called `MyScript.sc` that contains only `val elite = 31337`. You can import the script as follows:

```
import $file.MyScript
MyScript.elite
res1: Int = 31337
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

If the file is in a subfolder (e.g. **scripts**), use dot syntax: `import $file.scripts.MyScript`.

To go up one directory, use `^`.

### Adding Dependencies to the JVM `classpath` Dynamically <a href="#adding-dependencies-to-the-jvm-classpath-dynamically" id="adding-dependencies-to-the-jvm-classpath-dynamically"></a>

```
// java dependency
import $ivy.`com.michaelpollmeier:versionsort:1.0.1`
versionsort.VersionHelper.compare("2.1.0", "2.0.10")
// res: Int = 1

// scala dependency
import $ivy.`com.michaelpollmeier::colordiff:0.9`
colordiff.ColorDiff(List("a", "b"), List("a", "bb"))
// color coded diff
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

If the dependencies are not on Maven Central, you can add a resolver:

```
interp.repositories() ++= Seq(coursierapi.MavenRepository.of("https://shiftleft.jfrog.io/shiftleft/libs-snapshot-local"))
```

![](/files/CRrxFX9wuboXxDrdB2dv)

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

### Measuring the Time While Running a Computation <a href="#measuring-the-time-while-running-a-computation" id="measuring-the-time-while-running-a-computation"></a>

```
time { 
  println("long running computation")
  Thread.sleep(1000)
  42
}
// res: (42, 1000332390 nanoseconds)
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)
