Bash

在 bash 中使用 expect 來執行帶有密碼請求的命令

  • May 21, 2022

我已經花了一段時間製作一個BASH腳本來遍歷兩個列表並從中創建一個命令。

最後它應該執行命令並同步我的 ZFS 伺服器和 ZFS 備份伺服器。

唯一的頂峰是,BASH當命令要求輸入密碼時,它實際上無法插入密碼。

據我了解,這可以通過expect.

命令儲存在$ExecuteSyncoid And 看起來像這樣

/usr/sbin/syncoid <UserName>@<IP>:Storage/WallaBag Storage/Docker/WallaBag --compress none --sshcipher chacha20-poly1305@openssh.com --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"

但不幸的是,我無法弄清楚如何讓期望將$ExecuteSyncoid命令視為一個一致的命令。如果我將它放在引號“”中,它不會執行它,如果我沒有將它放在引號中,則$ExecuteSyncoidbash 變數被認為是期望的多個參數。


如果有人知道如何解決這個問題,或者知道該怎麼做,我將不勝感激。

如果我可以在expect命令執行時查看命令的輸出,那也太好了$ExecuteSyncoid

最好的問候, Darkyere

我不會審查每個變體。但是,shell 變數不會在單引號內展開。

查看最後一個變化:

外殼部分

ExecuteSyncoid="/usr/sbin/syncoid <UserName>@<IP>:Storage/WallaBag Storage/Docker/WallaBag --compress none --sshcipher chacha20-poly1305@openssh.com --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 的Argument 擴展語法:

spawn {*}$ExecuteSyncoid

您不想在發送時轉義期望 PWD 變數:刪除第一個反斜杠

send "$PWD\r"

除非您在期望中執行其他操作,否則在您發送密碼後,期望腳本將退出,這將終止同步程序。期望腳本的最後一行應該是以下之一:

  • 如果你,人類,需要與 syncoid 互動
interact
  • 如果你不需要互動
expect eof

引用自:https://unix.stackexchange.com/questions/703353