"Expect" automation tool output to shell variable

12,357

Since you're using expect with a here-doc in a bash script, you'd do:

output=$(
    expect << END
        expect script here
END
)

To reduce the output, add log_user 0 to the top of the expect body, and print the output of the GETINFO command

send -- "GETINFO circuit-status\r"
expect "250 OK\r"
puts $expect_out(buffer)

I mean this:

output=$(
    expect << EOD
        log_user 0
        spawn telnet localhost 9151
        expect "Escape character is '^]'."
        send -- "AUTHENTICATE $COOKIE\r"
        expect "250 OK\r"
        send -- "SIGNAL NEWNYM\r"
        expect "250 OK\r"
        send -- "GETINFO circuit-status\r"
        expect "250 OK\r"
        puts $expect_out(buffer)
        send -- "QUIT\r"
        expect eof
EOD
)
Share:
12,357

Related videos on Youtube

1.61803
Author by

1.61803

Updated on September 18, 2022

Comments

  • 1.61803
    1.61803 almost 2 years
    #!/bin/bash
    
    # more commands here
    
    expect << EOD
    spawn telnet localhost 9151
    expect -exact "Trying 127.0.0.1...\r
    Connected to localhost.\r
    Escape character is '^]'.\r"
    send -- "AUTHENTICATE $COOKIE\r"
    expect -exact "250 OK\r"
    send -- "SIGNAL NEWNYM\r"
    expect -exact "250 OK\r"
    send -- "GETINFO circuit-status\r"
    expect "250 OK\r"
    send -- "QUIT\r"
    expect -exact "250 closing connection\r
    Connection closed by foreign host.\r"
    EOD
    
    # more commands here
    

    This is about Expect. The script above establishes a telnet connection to the tor client and after clearing the current circuits, it gets the new circuit status.

    GETINFO circuit-status outputs something like

    250+circuit-status=
    7 BUILT $D313CCBD93E756A53CD667D0A1A97E82B7740067~melco,$DA24B9CD2AA8C02B9068A168C420DC302D969937=TorExit1488,$C00DE13988B4ABC93B43617C0FADAA8E1D4A0293=nabtor BUILD_FLAGS=NEED_CAPACITY PURPOSE=GENERAL TIME_CREATED=2014-02-09T13:11:29.264485
    5 BUILT $9DD5F90D641D835C4FCA7153148B156E6FD49CEE=darwinfish,$B013CA64C82EDC616BB3EC5DBE35BB7344EDFC2A=sipsrelay,$A59E1E7C7EAEE083D756EE1FF6EC31CA3D8651D7=chaoscomputerclub19 BUILD_FLAGS=IS_INTERNAL,NEED_CAPACITY,NEED_UPTIME PURPOSE=GENERAL TIME_CREATED=2014-02-09T13:11:05.263323
    4 BUILT $5B8CCA69DFD88B0281D5E67C7764CA6B5177F210=IchGebDirNeuland,$A587BBB611657B0743CD9E6E70B6497BE209FFD2=RelayW,$D313B081A3EFC5492BE95AFE39F715413DD35586=ToileLibre BUILD_FLAGS=IS_INTERNAL,NEED_CAPACITY,NEED_UPTIME PURPOSE=GENERAL TIME_CREATED=2014-02-09T13:11:04.263266
    2 BUILT $9DD5F90D641D835C4FCA7153148B156E6FD49CEE=darwinfish,$F16658975D729B8C4100A6DC649C5EDCAD1687A8=afo8,$35F51DCE73B988CBAE06B06312B4D1271979FE3B=thoreau BUILD_FLAGS=NEED_CAPACITY PURPOSE=GENERAL TIME_CREATED=2014-02-09T13:11:02.272687
    .
    250 OK
    

    I checked the man page, Exploring Expect - A Tcl-based Toolkit for Automating Interactive Programs (O'Reilly) and SO but I cannot make expect_out(buffer) work with set, set env nor puts.

    How can I put it in a variable for use in my bash script?

    How can I parse a part of it (e.g. C00DE13988B4ABC93B43617C0FADAA8E1D4A0293 above) and put it in a variable for bash?

  • 1.61803
    1.61803 over 10 years
    And how do you redirect the output of expect to a file? That said, I want to do it from expect to bash.
  • Marki
    Marki over 10 years
    See my edit... Why would you not be able to redirect? Create a shell script that runs expect test.xp > test.out and parse what's in test.out after that
  • Angel Todorov
    Angel Todorov about 10 years
    That's what I am attempting to help you with. I just didn't spoonfeed you the solution. How have I confused you?
  • 1.61803
    1.61803 about 10 years
    I already use var A for the expect script, and another var B to cut a string out of var A's output (no need to use puts as in your suggestion). I want to get rid of both vars, run expect in bash and return only GETINFO's value to some expect's default var that I can use directly in bash, if possible.
  • Angel Todorov
    Angel Todorov about 10 years
    have you tried my suggestions?
  • 1.61803
    1.61803 about 10 years
    I already had in place your first suggestion like this NEW_CIRCUIT=$(expect << EOD send -- "GETINFO circuit-status\r" expect "250 OK\r" EOD) EXIT_NODE_FP=$(echo $NEW_CIRCUIT | cut ) but, again, I want to get rid of $NEW_CIRCUIT and $EXIT_NODE_FP like I explained