簡體   English   中英

無法通過expect SSH bash 命令的腳本

[英]Unable to SSH a script of bash commands via expect

我正在嘗試將一組命令推送到多個遠程主機。 我可以根據個人情況使用以下內容:
ssh user@remoteHost "bash -s" <./commands.sh
我可以把它放到一個循環中,但后來我被困在輸入密碼 n 次。 禁用 SSH 配置文件中的密碼提示對我來說不是一個選項。 我試圖在循環中使用 expect ,但我無法讓它工作。

#!/bin/bash  
HOSTS="host1 host2"  
read -sp "Password: " PASSWORD  
for HOST in $HOSTS; do  
    expect -c "  
    spawn /usr/bin/ssh user@$HOST "bash -s" <./commands.sh  
    expect_before {
        "*yes/no*" {send "yes"\r;exp_continue}}
    expect {
        "*Password*" {send $PASSWORD\r;interact}}
    exit"
done

我收到以下錯誤:

spawn /usr/bin/ssh root@host1 bash  
expect: invalid option -- 's'  
usage: expect [-div] [-c cmds] [[-f] cmdfile] [args]  
spawn /usr/bin/ssh root@host2 bash  
expect: invalid option -- 's'  
usage: expect [-div] [-c cmds] [[-f] cmdfile] [args]  

有任何想法嗎? 似乎expect 正在嘗試解釋bash 命令。 我不確定如何阻止這種情況。

解決方案:
代替
spawn /usr/bin/ssh user@$HOST "bash -s" <./commands.sh

spawn sh -c {ssh root@$HOST 'bash -ls' < /tmp/commands.sh}
最終代碼:

#!/bin/bash

HOSTS="host1 host2"

read -sp "Password: " PASSWORD

for HOST in $HOSTS; do
        expect -c "
                spawn sh -c {ssh root@$HOST 'bash -ls' < /tmp/commands.sh}
                expect_before {
                "*yes/no*" {send "yes"\r;exp_continue}}
                expect {
                "*assword*" {send $PASSWORD\r;interact}}
                exit"
done

我建議這樣做:

#!/bin/bash  
hosts=(host1 host2)
read -sp "Password: " password  
for host in "${hosts[@]}"; do  
    env h="$host" p="$password" expect <<'END_EXPECT'
        spawn sh -c "/usr/bin/ssh user@$env(h) 'bash -s' <./commands.sh"
        expect {
            "*yes/no*"   {send "yes\r"; exp_continue}
            "*Password*" {send "$env(p)\r"}
        }
        interact
END_EXPECT
done

筆記

  • 使用小寫變量名:保留大寫變量名供 shell 使用
  • 使用引用的 heredoc 來包含期望代碼
    • 這讓你可以在 expect 中使用單引號和雙引號,而不必擔心在 shell 中引用地獄
  • 使用env通過環境傳遞 shell 變量來期望
  • 簡化您的期望聲明

使用的危險

expect -c " ...; expect "*Password*" ..."

是內部雙引號與外部引號匹配,並被外殼刪除。 這使得*Password*成為 shell 可以根據當前目錄中的文件和 shell 設置進行擴展的裸 glob。 例如,創建一個名為“The Password”(帶有空格)的文件,您將收到錯誤消息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM