Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expect Script - Fixing weird terminal resizing behaviour

I wrote a small expect script to connect to multiple SSH Servers. However if I interact with the terminal after initializing the connection, the terminal window behaves very odd.

For example, if I start the script in a non-fullsize terminal, and resize the window to make it larger after the Interact, it looks like that:

Weird Terminal Preview

Now, I had this issue in my first expect script as well. But I was able to resolve it by adding the following code:

trap {
    set XZ [stty rows   ]
    set YZ [stty columns]
    stty rows $XZ columns $YZ < $spawn_out(slave,name)
} WINCH

And this worked perfectly fine! I was able to resize the terminal without a problem.

However, I added this piece of code to my new script, where there are multiple interact's in different proc's (functions). And on window resize, I get the following error:

can't read "spawn_out(slave,name)": no such variable

while executing

"stty rows $XZ columns $YZ < $spawn_out(slave,name)"

I have no idea on how to resolve this. Here is my code:

#!/usr/bin/expect -f

set SERVER "0"
set CHOICE "0"

set SERVER_1_PKEY [exec cat /home/me/p1]
set SERVER_2_PKEY [exec cat /home/me/p2]

set SERVER_1_HOST "server1.com"
set SERVER_2_HOST "server2.com"

set SERVER_1_USER "server1user"
set SERVER_2_USER "server2user"

set SERVER_1_PORT "22"
set SERVER_2_PORT "22"

trap {
    set XZ [stty rows   ]
    set YZ [stty columns]
    stty rows $XZ columns $YZ < $spawn_out(slave,name)
} WINCH

proc s1 {SERVER_1_PKEY SERVER_1_HOST SERVER_1_USER SERVER_1_PORT} {
    send_user "\033c"
    spawn ssh ${SERVER_1_USER}@${SERVER_1_HOST} -p ${SERVER_1_PORT}
    expect "assword:"
    send "${SERVER_1_PKEY}\r"
    interact
}

proc s2 {} {
    send_user "\033c"
    spawn ssh ${SERVER_2_USER}@${SERVER_2_HOST} -p ${SERVER_2_PORT}
    expect "assword:"
    send "${SERVER_2_PKEY}\r"
    interact
}

set arg [lindex $argv 0]
switch $arg {
    ""  { set CHOICE "0" }
    "1" { set CHOICE "1" }
    "2" { set CHOICE "2" }
}

if {$CHOICE eq "0"} {
    puts -nonewline " Input \[1,2\]: "
    flush stdout
    gets stdin SERVER
    if {$SERVER eq "1"} { s1 $SERVER_1_PKEY $SERVER_1_HOST $SERVER_1_USER $SERVER_1_PORT }
    if {$SERVER eq "2"} { s2 $SERVER_2_PKEY $SERVER_2_HOST $SERVER_2_USER $SERVER_2_PORT }
}

if {$CHOICE eq "1"} { s1 $SERVER_1_PKEY $SERVER_1_HOST $SERVER_1_USER $SERVER_1_PORT }
if {$CHOICE eq "2"} { s2 $SERVER_2_PKEY $SERVER_2_HOST $SERVER_2_USER $SERVER_2_PORT }

Can anyone help me resolve this issue or tell me what I'm missing?

like image 715
NullDev Avatar asked Oct 30 '22 04:10

NullDev


1 Answers

When you call spawn inside a procedure the array variable spawn_out(slave,name) has the scope of that procedure only. Usually, you can just make this into a global scope by declaring it as such inside each procedure:

proc s1 {...} {
  global spawn_out
  ...
  spawn ...
}
send_user $spawn_out(slave,name)
like image 147
meuh Avatar answered Nov 15 '22 12:11

meuh