Search code examples
shellunixexpect

variable usage in expect script


Text of attribute.csv
"dog","6"
"cat","3"
"mikeymouse","10"

firstScript.sh
#!/bin/bash
echo "Start Say"
read a
while((1))
do
    echo -n "Master: "
    read animal
    if [[ $animal = "dog" ]];then
        echo "Age: 6"
    elif [[ $animal = "cat" ]];then
        echo "Age: 3"
    elif [[ $animal = "mikeymouse" ]];then
        echo "Age: 10"
    fi
done

secondScript.sh
#!/bin/bash
export line=`wc -l ~/Desktop/attribute.csv | awk {'print $1'}`
expect -c '
    set timeout 3
    spawn /Users/dog/Desktop/firstScript.sh
    expect {
        "Start Say" {send "\r";exp_continue}
        "Master: " {
            for {set i 1} {$i<=$env(line)} {incr i} {
                send [exec bash -c {awk -F '\''"'\'' {'\''print $2'\''} ~/Desktop/attribute.csv | sed -n "$i"p}]\r
            }
            interact
        }
        timeout {puts "\nTimeout";exit 0}
    }
'
echo ""

actual outcome:
$ /Users/dog/Desktop/secondScript.sh
spawn /Users/dog/Desktop/firstScript.sh
Start Say

Master: dog
cat
mikeymouse
Age: 6
Master: Age: 3
Master: Age: 10
Master: dog
cat
mikeymouse
Age: 6
Master: Age: 3
Master: Age: 10
Master:

$

The problem is I cannot get my expect result as below:
$ /Users/dog/Desktop/secondScript.sh
spawn /Users/dog/Desktop/firstScript.sh
Start Say

Master: dog
Age: 6
Master: cat
Age: 3
Master: mikeymouse
Age: 10
Master:


Solution

    1. mixing expect into a shell script, you're best using a quoted heredoc to avoid quoting hell
    2. you don't need to exec out to awk and sed, Tcl can easily read a file
    3. single quotes have no special meaning in Tcl, use braces instead.
    4. CSV can be surprisingly tricky to get right, use a well tested library.
    5. smart to use the environment to pass data into expect.
    #!/bin/bash
    export csv=$HOME/Desktop/attribute.csv
    expect <<'END_EXPECT'
        # from tcllib
        package require csv
    
        set fh [open $env(csv) r]
        while {[gets $fh line] != -1} {
            lappend animals [lindex [csv::split $line] 0]
        }
        close $fh
    
        set timeout 3
        set idx -1
    
        spawn $env(HOME)/Desktop/firstScript.sh
        expect {
            "Start Say" {send "\r"; exp_continue}
            "Master: " {
                if {[incr idx] == [llength $animals]} {
                    exit
                }
                send "[lindex $animals $idx]\r"
                exp_continue
            }
            timeout    {puts "\nTimeout";exit}
        }
    END_EXPECT
    echo ""