如何在Expect条件语句中使用Bash脚本变量

9

我正在编写一个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....."

使用Expect脚本代替可以解决第一个问题。对于日志问题,使用log_user 0log_file -a <file>可以解决。


你需要“设置bashaction”吗?为什么不直接在if语句中引用$ strAction呢? - Eric Smith
3个回答

15

你不需要使用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语法可能会有些不太熟悉,但你应该可以轻松扩展上述示例代码。


谢谢。我也做了同样的事情。再次执行此脚本是由C程序控制的,我想将输出重定向到日志文件(该文件也是动态的)。我能做到这一点并抑制所有标准输出吗? - puneet agrawal
@puneetagrawal 这里是你关于在Linux中重定向命令输入/输出的答案:https://dev59.com/CkXRa4cB1Zd3GeqPso7W - neam

6

从TCL和Expect中访问环境变量

由于您正在从另一个进程调用此Expect脚本,因此可以利用环境变量。例如,如果您的父进程已将action导出到环境中,则可以使用以下方式在您的expect脚本中访问其值:

$::env(action)

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

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

禁用标准输出日志记录

为了禁用生成的进程的标准输出日志记录,Expect提供了log_user命令。您可以使用log_user 0防止生成的进程写入stdout。

expect(1)手册说:

默认情况下,发送/期望对话记录在stdout(以及如果打开则在日志文件中)。通过命令“log_user 0”禁用stdout的记录,并通过“log_user 1”重新启用。记录到日志文件的方式不变。

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

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

0

为了抑制标准输出,您可以使用以下方法:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接