bash 如何在expect条件语句中使用bash脚本变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11131318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:17:37  来源:igfitidea点击:

How to use bash script variables in expect conditional statements

bashexpect

提问by puneet agrawal

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. Can somebody help in this. Also, 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
here is the code

我正在编写一个 bash 脚本并使用 expect 来执行 sftp。现在在 expect 块中,我想在条件语句中访问 bash 变量。但是,我无法这样做。有人可以帮忙吗。此外,此脚本的执行由 ac 程序控制,我不想将输出重定向到日志文件(这也是动态的)。我可以这样做并抑制 stdout 上的所有输出,
这是代码

!/usr/bin/bash   
host=  
user=  
pass=  
action=  
path=  
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 expect script instead worked.
for logging issue, using log_user 0 and log_file -a helped

对于 1. 使用期望脚本代替工作。
对于日志记录问题,使用 log_user 0 和 log_file -a 有帮助

回答by Hai Vu

You don't need to use bash, expectcan handle all that:

你不需要使用bashexpect可以处理所有这些:

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

来自bash,Tcl/Expect 语法有点奇怪,但是扩展上述框架应该没有任何问题。祝你好运。

回答by Todd A. Jacobs

Accessing Environment Variables from TCL and Expect

从 TCL 和 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 actionto the environment, then you can access its value within your expect script with:

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

$::env(action)

In Bash, you can mark the variable for exportwith the exportbuiltin. For example:

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

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.

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

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.

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

The expect(1) manual says:

expect(1) 手册说:

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.

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

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

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

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

回答by Nit

To suppress output to the stdout you can use

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

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

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

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