bash 如何在expect中设置bash变量或从expect返回变量到bash

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11970608/
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-18 03:02:30  来源:igfitidea点击:

how to set bash variable in expect or return variable from expect to bash

linuxbashshell

提问by barp

 VAR=$(expect -c ' 
 spawn ssh-copy-id -i '"$SSH_KEY_PATH_PUB $REMOTE_HOST_USER@$REMOTE_HOST_IP"' 
 expect "*?assword:*" 
 send "'"$REMOTE_HOST_PASSWD"'\r"; 
 expect {
 "Permission denied, please try again."{ 
 send user "Wrong pass" 
 exit 5
 }
 }
 ')
 echo "$VAR"

UPDATE: So I need the exit condition when the code enters the Permission denied block.I am lookin at $?

更新:所以当代码进入 Permission denied 块时我需要退出条件。我在看 $?

But it is 0 because "$VAR" runs succesfully.

但它是 0,因为 "$VAR" 运行成功。

So I need a an integer return value when it enters Permission denied block

所以当它进入 Permission denied 块时我需要一个整数返回值

回答by twmb

Expect starts its own tcl shell, so you cannot use aliases defined in your bash environment.

Expect 启动它自己的 tcl shell,因此您不能使用在 bash 环境中定义的别名。

Expect does have the variable $env(YOURBASHVARIABLE), which allows Expect to grab your environment variables, but Expect can only modify them internal to the script. However, any modifications you make to the variable will not be kept once the expect script is finished.

Expect 确实有变量$env(YOURBASHVARIABLE),它允许 Expect 获取您的环境变量,但是 Expect 只能在脚本内部修改它们。但是,一旦expect 脚本完成,您对变量所做的任何修改都不会保留。

If flag is going to be a number, you could use an exit status (e.g., exit 5) and then use $?in your script to get the exit status.

如果 flag 将是一个数字,您可以使用退出状态(例如,exit 5),然后$?在您的脚本中使用以获取退出状态。

Per your updateThe expect script doesn't return anything, it just sets an exit code.

根据您的更新预期脚本不返回任何内容,它只是设置一个退出代码。

What you could do is simply:

你可以做的很简单:

$(expect -c ' 
  spawn ssh-copy-id -i '"$SSH_KEY_PATH_PUB $REMOTE_HOST_USER@$REMOTE_HOST_IP"' 
  expect "*?assword:*" 
  send "'"$REMOTE_HOST_PASSWD"'\r"; 
  expect {
    "Permission denied, please try again."{ 
      send user "Wrong pass" 
      exit 5
    }
  }
'); var=$?

This way, varwill be set to your exit status.

这样,var将设置为您的退出状态。

Also, you should take note of this:

另外,你应该注意这一点:

By convention, environment variables (PATH, EDITOR, SHELL, ...) and internal shell variables (BASH_VERSION, RANDOM, ...) are fully capitalized. All other variable names should have at least one lowercase letter. Since variable names are case-sensitive, this convention avoids accidentally overriding environmental and internal variables.

按照惯例,环境变量 (PATH, EDITOR, SHELL, ...) 和内部 shell 变量 (BASH_VERSION, RANDOM, ...) 完全大写。所有其他变量名称应至少有一个小写字母。由于变量名称区分大小写,此约定可避免意外覆盖环境变量和内部变量。

EDIT(mpapis): there is also other use case:

编辑(mpapis):还有其他用例:

if output="$(expect ...)"
then
  echo "it worked: $output"
else
  result=$?
  echo "it failed($result): $output"
fi

EDIT(twmb)

编辑(twmb)

With the last use case, you have to be careful with what you are returning. It will take all output sent to the user. Unless you have logging turned off (with log_user 0) and you are controlling exactly what will be outputted in the expect script, you will probably get more information than needed.

对于最后一个用例,您必须小心返回的内容。它将把所有输出发送给用户。除非您关闭了日志记录(使用log_user 0)并且您正在精确控制将在期望脚本中输出的内容,否则您可能会获得比需要的更多的信息。

Another drag with this is indicated in the comment below;

下面的评论中指出了与此相关的另一个阻力;

returned="$(expect -c '
  log_user 1  ;# turn to 0 and use send_user to control the exact output
  spawn bash
  expect "\$"
  send "echo hello\r"
  send_user "this will be returned"
  expect "\$" ;# without this line, the script would exit too fast 
               ;# for the "echo hello" to be sent to stdout by bash
               ;# and thus wont be recorded
  exit 6
  '
  )"; var=$?
echo "var: $var"
echo "returned: $returned"

回答by Karoly Horvath

In this case, VARcontains the outputof the command.

在这种情况下,VAR包含output命令的 。

You have to use $?, which contains the exit status of the last command executed. Setting a variable doesn't alter $?, so it will still contain the exit status of the subshell $(...).

您必须使用$?,其中包含最后执行的命令的退出状态。设置变量不会改变$?,因此它仍将包含子外壳的退出状态$(...)

Example:

例子:

x=$(expect -c 'send "hello"; exit 5;')
echo $?; echo $x
5
hello

回答by Stephane Rouberol

In expect you can use set envto manipulate environment variables. If a number, you can pass variable from expect to bash thanx to exit command. Let's see an example:

在expect中你可以set env用来操作环境变量。如果是数字,您可以将变量从 expect 传递到 bash thanx 到 exit 命令。让我们看一个例子:

~/Desktop> cat test.exp
puts "From shell: FLAG=$env(FLAG)"
set env(FLAG) 22
puts "Set by expect: FLAG=$env(FLAG)"
exit $env(FLAG)
~/Desktop> export FLAG=0
~/Desktop> expect test.exp 
From shell: FLAG=0
Set by expect: FLAG=22
~/Desktop> echo $?
22
~/Desktop>