在bash中使用expect来执行带有密码请求的命令

在bash中使用expect来执行带有密码请求的命令

我已经花了一段时间制作一个BASH脚本来遍历两个列表并从中创建一个命令。

最后它应该执行命令并同步我的 ZFS 服务器和 ZFS 备份服务器。

唯一的顶峰是,BASH当命令要求输入密码时,实际上无法插入密码。

据我了解,这可以通过expect.

该命令存储在$ExecuteSyncoid 并且看起来像这样

/usr/sbin/syncoid <UserName>@<IP>:Storage/WallaBag Storage/Docker/WallaBag --compress none --sshcipher [email protected] --sshport <PortNumber> --sshkey </dest/to/keyfile> --no-privilege-elevation

密码存储在$PWD

现在我必须expect从 BASH 中执行,因为我真的没有心情尝试重新创建expect/tcl我以前从未尝试过的所有代码。

expect部分是

Enter passphrase for key '<nameOfKey>'

现在我不明白,tcl/expect 但到目前为止我已经做出了尝试,但我只是无法让它工作一次

expect -c 'expect "Enter" { spawn $ExecuteCommand; send -- "$PWD\r"; interact }'


expect -c 'spawn $ExecuteSyncoid; expect "Enter"; send -- "$PWD\r"; interact'


syncoid command/password
/usr/bin/expect - <<EOF
    spawn $ExecuteSyncoid
    expect "Enter"
    send -- "$PWD\r"
EOF


/usr/bin/expect <<EOD
spawn $ExecuteSyncoid
expect "Enter passphrase for key"
send -- "$PWD\r"
interact
EOD


/usr/bin/expect -c 'expect "Enter" { spawn $ExecuteSyncoid; send -- "$PWD\r" }'

我也尝试制作一个单独的脚本

expect -f ./SynCoid-IterateThroughDataSets.exp $ExecuteSyncoid $PWD

用代码

#!/usr/bin/expect -f 
set ExecuteSyncoid [lindex $argv 0];
set PWD [lindex $argv 1];
spawn $ExecuteSyncoid
expect "Enter"
send "\$PWD\r"

但不幸的是,我无法弄清楚如何使 Expect 将$ExecuteSyncoid命令视为一个一致的命令。如果我把它放在引号“”中,并且如果我没有将它放在引号中,那么$ExecuteSyncoidbash 变量将被视为期望中的多个参数。


如果有人知道如何解决这个问题,或者知道该怎么做,我将不胜感激。

expect如果我可以在命令执行时查看命令的输出,那就太好了$ExecuteSyncoid

最好的问候,达耶尔

答案1

我不会审查每个变体。但是 shell 变量不会在单引号内扩展。

看看最后一个变体:

外壳部分

ExecuteSyncoid="/usr/sbin/syncoid <UserName>@<IP>:Storage/WallaBag Storage/Docker/WallaBag --compress none --sshcipher [email protected] --sshport <PortNumber> --sshkey </dest/to/keyfile> --no-privilege-elevation"
PassWord="abc123"      # Don't use PWD!

expect -f ./SynCoid-IterateThroughDataSets.exp $ExecuteSyncoid $PassWord

因为变量没有被引用,所以它们经历分词:期望脚本将看到 13 个参数,而不是 2 个。

始终引用您的变量:

expect -f ./SynCoid-IterateThroughDataSets.exp "$ExecuteSyncoid" "$PassWord"

期待部分

#!/usr/bin/expect -f 
set ExecuteSyncoid [lindex $argv 0];
set PWD [lindex $argv 1];          # this has nothing to do with the shell's PWD variable
spawn $ExecuteSyncoid
expect "Enter"
send "\$PWD\r"

现在 shell 变量已被引用,expect 变量ExecuteSyncoid是一个包含空格的单词。

spawn命令需要扩展该单词,因此我们将使用 Tcl 的论证扩展句法:

spawn {*}$ExecuteSyncoid

您不想在发送时转义期望的 PWD 变量:删除第一个反斜杠

send "$PWD\r"

除非您在expect中执行其他操作,否则在发送密码后,expect脚本将退出,这将终止syncoid进程。 Expect 脚本的最后一行应该是以下之一:

  • 如果你,人类,需要与 Synoid 交互
    interact
    
  • 如果你不需要互动
    expect eof
    

相关内容