0
 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"

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

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

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

4

3 回答 3

1

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

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.

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.

Per your update The 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, var will be set to your exit status.

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.

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

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

EDIT(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.

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"
于 2012-08-15T14:58:38.320 回答
1

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

您必须使用$?,其中包含最后执行的命令的退出状态。设置一个变量不会改变$?,所以它仍然会包含 subshel​​l 的退出状态$(...)

例子:

x=$(expect -c 'send "hello"; exit 5;')
echo $?; echo $x
5
hello
于 2012-08-15T16:36:45.073 回答
0

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

~/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> 
于 2012-08-15T14:56:57.437 回答