Guide to expert, an awesome tool to automatically interact with applications that run in terminal
Tags: linux
Published: 2019-09-19 15:51:34

---
title: Guide to expert, an awesome tool to automatically interact with applications that run in terminal
published: true
tags: linux
canonical_url: https://thecodersblog.com/expect-guide-for-linux/
---

 **Expect** is an awesome tool to automatically interact with applications that run in terminal. **Expect** script allows us to start an application, then to monitor the **stdout** and to send messages to the **stdin** of that application when it detects a certain **stdout** pattern occurs.

## Basic concept

Core functionality of **Expect** consists of: **spawn** , **expect** , and **send**.

1. **spawn** : start the process that we want to monitor/control.
2. **expect** : wait and only do the next action when other detect a certain pattern in the monitored stdout or timeout is triggered.
3. **send** : send text to the stdin of the monitored application.

Other build-in variables and functions:

- **timeout** : setting timeout for expect. (_-1_) means disabling timeout.
- **puts** : write text to the interactive screen.
- **wait** : wait until the monitored process stops.
- **sleep** : sleep the expect script for a certain amount of time.
- **$argv** : array of input parameters.
- **eof** : the pattern that occurs when a spawn process is closed.
- **lindex** : access array element.
- **interact** : give user the interaction control.

**Expect** also provides the concept of global and local variables and functions:

- The following pseudo-code defines function **runcmd** with three parameters: **X** , **Y** , **Z**.
- Keyword **global** is used to access **VAR** from inside **runcmd**.
- **$X** refers to variable **X**.
- Line with **#** at the beginning indicates comments.
- **arg1** and **arg2** capture input parameters.

```
set arg1 [lindex $argv 0]
set arg2 [lindex $argv 1]

set VAR "..."

# define function runcmd
proc runcmd{ X , Y , Z } {

    global VAR
    ...
    puts "X=$X"
}
# call function runcmd with X=A,Y=B,Z=C
runcmd A,B,C
```

## Examples

The following function tries to access to a ssh server that requires to enter password and run a script in a certain directory. Script, directory, and server are input parameters of that function. In the main script, that function is called to _stop tomcat service_ inside _/opt/tomcat_.

```
SET SSHPWD "xxxxxx"
#--------------------------------------------------------------------
# run cmd in directory of remote server 
#--------------------------------------------------------------------
proc runcmd { script , dir , server } {

    global SSHPWD

    puts "------------------------------------------------------------"
    puts " run - $script - in - $dir - of - $server -"
    puts "------------------------------------------------------------"

    # never timeout
    set timeout -1 

    # login remote server
    spawn ssh $server
    expect "password:"
    send "$SSHPWD\r"

    # change to root
    expect "\[user@"  
    send "sudo -s\r"
    expect "root@"
    
    # run cmd  
    send "cd $dir\r"
    send "pwd\r"
    send "\r"
    send "$script \r"
    send "\r"

    # logout    
    send "exit\r"
    send "exit\r"

    # connection is closed
    expect "closed\."
    
    puts "------------------------------------------------------------"
    puts " finish - $script -"
    puts "------------------------------------------------------------"

    sleep 10

}

runcmd "service tomcat7 stop" , "/opt/tomcat/" , "server"
```