6

我正在编写一个 Bash 脚本并使用 Expect 来执行 sftp。现在在 Expect 块中,我想在条件语句中访问 Bash 变量。但是,我无法这样做。怎么能做到这一点?

此外,此脚本的执行由 C 程序控制,我想将输出重定向到日志文件(这也是动态的)。我可以这样做并抑制标准输出上的所有输出。

这是代码:

!/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....."

1. 改为使用 Expect 脚本。对于日志记录问题,使用log_user 0log_file -a <file>帮助。

4

3 回答 3

14

你不需要使用 Bash。Expect 可以处理所有这些:

#!/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....."

来自 Bash,Tcl/Expect 语法有点奇怪,但是扩展上面的框架应该没有任何问题。

于 2012-06-21T05:17:06.960 回答
4

从 TCL 和 Expect 访问环境变量

由于您是从另一个进程调用此 Expect 脚本,因此您可以使用环境变量。例如,如果您的父进程已将操作导出到环境,那么您可以在期望脚本中访问其值:

$::env(action)

在 Bash 中,您可以使用内置的export标记要导出的变量。例如:

export action

由于我不确定您是如何从 C 中调用 Expect 脚本的,因此您需要确保正确导出变量。

禁用记录到标准输出

为了禁用从衍生进程到标准输出的日志记录,Expect 提供了 log_user 命令。您可以使用log_user 0.

expect(1) 手册说:

默认情况下,发送/预期对话记录到标准输出(如果打开,还有一个日志文件)。命令“log_user 0”禁用记录到标准输出,并由“log_user 1”重新启用。记录到日志文件没有改变。

这实际上并没有关闭标准输出,这通常不是您想要的。这样做会导致写入 stdout 的任何内容抛出如下错误:

can not find channel named "stdout"
    while executing
"puts hello"
    (file "/tmp/foo" line 8)
于 2012-06-24T16:25:02.573 回答
0

要抑制输出到标准输出,您可以使用

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

要写入日志文件,可以使用类似的管道 (>>>),或者tee如果要将输出写入长管道的中间,则可以使用命令。

于 2012-06-21T06:09:25.603 回答