9

I am writing a Bash script and using Expect to do sftp. Now in the Expect block I want to access a Bash variable in a conditional statement. But, I am unable to do so. How can do this?

Also, the execution of this script is controlled from a C program and I want redirect the output to a log file (which again is dynamic). Can I do that and suppress all the output on standard output.

Here is the code:

!/usr/bin/bash
host=$1
user=$2
pass=$3
action=$4
path=$5
echo "Starting...."

function doAction {

strAction="\""$action"\""
echo $strAction

/usr/bin/expect <<EOF > logfile.txt
**set bashaction $strAction**
spawn sftp $user@$host

expect "password:"
send "$pass\r"
expect"sftp>"
send "cd $path\r"
**if {$bashaction == "TEST"} {**
  expect "sftp>"
  send "prompt\r"
}

expect "sftp>"
send <sftp command>
expect "sftp>"
send_user "quit\n"

exit
  EOF
}

doAction
echo "DONE....."

For 1. using an Expect script instead worked. For the logging issue, using log_user 0 and log_file -a <file> helped.

1
  • Do you need to set bashaction? Why not just refer to $strAction directly in your if statement? Commented Jun 21, 2012 at 5:06

3 Answers 3

15

You don't need to use Bash. Expect can handle all that:

#!/usr/bin/expect

set host [lindex $argv 0]
set user [lindex $argv 1]
set pass [lindex $argv 2]
set action [lindex $argv 3]
set path [lindex $argv 4]
puts "Starting...."

puts "\"$action\""
spawn sftp $user@$host

expect "password:"
send "$pass\r"

expect"sftp>"
send "cd $path\r"

if {$action == "TEST"} {
    # Do something
} else {
    # Do something else
}

expect "sftp>"
send_user "quit\r"

puts "DONE....."

Coming from Bash, the Tcl/Expect syntax is a little strange, but you should not have any problem expanding the above skeleton.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks. I did the same thing. Again the execution of this script is controlled from a c prograame and i wan't redirect the output to a log file (which again is dynamic). Can i do that and suppress all teh output on stdout
@puneetagrawal here is your answer for redirecting input/output of the command
6

Accessing Environment Variables from TCL and Expect

Since you are calling this Expect script from another process, you can make use of environment variables. For example, if your parent process has exported action to the environment, then you can access its value within your expect script with:

$::env(action)

In Bash, you can mark the variable for export with the export builtin. For example:

export action

Since I'm not sure how you're invoking the Expect script from C, it's up to you to make sure the variable is properly exported.

Disable Logging to Standard Output

To disable logging to standard output from spawned processes, Expect provides the log_user command. You can prevent your spawned processes from writing to stdout with log_user 0.

The expect(1) manual says:

By default, the send/expect dialogue is logged to stdout (and a logfile if open). The logging to stdout is disabled by the command "log_user 0" and reenabled by "log_user 1". Logging to the logfile is unchanged.

This doesn't actually close standard output, which is generally not what you want anyway. Doing so will cause anything that writes to stdout to throw an error like this:

can not find channel named "stdout"
    while executing
"puts hello"
    (file "/tmp/foo" line 8)

Comments

0

To suppress output to the standard output you can use

command here >/dev/null 2>/dev/null

To write to a log file, you can use similar piping (> or >>), or the tee command if you want to write the output in the middle of a long pipe.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.