How to Pass Local Shell Script Variable to Expect

how to pass shell variable into expect within shell script

Be careful what you are talking about. We have shell variables and we have exported shell variables a.k.a. environment variables. In your code, you have an environment variable, because you export it.

I answer here therefore for accessing environment variables from within the expect program. If you are really concerned about shell variables, please clarify this in your posting.

First, I strongly recommend to use ALL UPPERCASE names for environment variables. Having lower case in the name of an environ might or might not work, depending on the concrete case.

Now assume I have an environment variable FOO, and I want to access it within expect. This can be done in two ways, using the builtin array env:

$::env(FOO)
[set ::env(FOO)]

BTW, in cases like yours, you do not need the double-colon; for instance $env(FOO) would do the same. However, if you get used to write the ::, you will be on the safe side in case you have to maintain more complex expect programs.

How to pass variables from a shell script to an expect script?

From your shell script:

/mypath/abc $gateway

From your expect script:

#!/usr/bin/expect

set gateway [lindex $argv 0]; # Grab the first command line parameter

set timeout 3
spawn ssh "james@$gateway"
expect "password:"
send "TSfdsHhtfs\r";
interact

Passing variable to `expect` in bash array

The problem is with quoting. Single quotes surrounding the whole block don't let Bash expand variables ($instance).

You need to switch to double quotes. But then, double quotes inside double quotes are not allowed (unless you escape them), so we are better off using single quotes with expect strings.

Try instead:

for instance in ${INSTANCE_IPS[@]}
do
echo $instance
/usr/bin/expect -c "
spawn ssh root@$instance;
expect '?assword: ';
send '<password>\r';
expect '# ';
send '. /usr/local/bin/bootstrap.sh\r';
expect '# ';
send 'exit\r' "
done

How can I pass a shell script variable into an Expect script?

Oh, I see. You want $SPACE to hold the COMMAND, not the VALUE. This construct will execute the command and save the output in the variable: x=$(cmd arg arg). So you are finding the space used on your local host and sending that value to the remote host.

You need something like this:

#!/bin/bash
export cmd="df -h | awk '{ print \$5 }' | grep -v Use |sort -n |tail -1 | cut -d % -f1"
remote_usage=$(
expect <<'EOF'
log_user 0
spawn -noecho ssh "root@192.168.53.197"
expect "Password:"
send "*****\r"
expect "prompt"
send "$env(cmd)\r"
expect -re {(?n)^(\d+)$.*prompt}
send_user "$expect_out(1,string)\n"
send "exit\r"
expect eof
EOF
)
echo "disk usage on remote host: $remote_usage"

However, you don't have to do any of that. Set up SSH keys (with ssh-keygen and ssh-copy-id) and do

remote_usage=$( ssh root@192.168.53.197 sh -c "df -h | awk '{ print \$5 }' | grep -v Use |sort -n |tail -1 | cut -d % -f1" )

How to pass variable to exec command in expect script?

Tcl {braces} are like shell 'single quotes' -- no variable expansion is performed within.

You need to use different quoting:

set value "PublicKey"
set cmd "cat .pass | cut -d'&' -f1 | openssl base64 -d | openssl enc -d -rc2 -k $value"
set output [ exec sh -c $cmd ]
puts $output

expect into remote system, get output to local shell variable

#!/usr/bin/expect --
log_user 0
set timeout 60
spawn ssh user@server.domain.com
expect {
timeout {puts "timed out after $timeout seconds"; exit}
"Password:"
}
send "mypassword\r"
expect "user$ "
send "date\r"
expect "date\r\n"
expect "*\r" { send_user "$expect_out(0,string)\n" }
close
exit


Related Topics



Leave a reply



Submit