gpt4 book ai didi

linux - 使用 expect 在远程机器上运行脚本

转载 作者:太空宇宙 更新时间:2023-11-04 12:02:08 27 4
gpt4 key购买 nike

我正在做一个需要一些帮助的项目。

我已将完成此项目所需的大部分信息自动化,但唯一滞后的是在远程计算机上运行本地 shell 脚本。正如我们所知,使用“expect”库的脚本无法识别任何 Linux 命令。这里有两个我尝试过的用例:

1) 仅使用一个 expect 脚本在远程服务器上运行所需的命令列表,该脚本具有脚本执行以及使用 scp 将输出推送到本地机器,这里是这段代码的片段:

`chmod 777 localscript.sh   
cat > script1.sh <<- "ALL"`
`#!/usr/bin/expect
set password [lindex $argv 0];
set ipaddress [lindex $argv 1];
set timevalue [lindex $argv 2];
set timeout $timevalue
spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
expect "assword:"
send "$password\r"
set timeout $timevalue
spawn /usr/bin/scp username@$2:"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$password\r"
interact
ALL
chmod 777 script1.sh
./script1.sh $password $2 $timevalue`

2) 在单独的 expect 脚本中在远程服务器上运行所需的命令列表,并使用 scp 在不同的脚本中获取文件:

`cat > script1.sh <<- "ALL" ` 
`#!/usr/bin/expect
set password [lindex $argv 0];
set ipaddress [lindex $argv 1];
set timevalue [lindex $argv 2];
set timeout $timevalue
spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
expect "assword:"
send "$password\r"
interact
ALL
cat > script2.sh <<- "ALL2"`
`#!/usr/bin/expect
set password [lindex $argv 0];
set ipaddress [lindex $argv 1];
set timevalue [lindex $argv 2];
set timeout $timevalue
spawn /usr/bin/scp username@ipaddress:"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$password\r"
interact
ALL2
chmod 777 localscript.sh script1.sh script2.sh
./script1.sh $password $2 $timevalue
sleep 5
./script2.sh $password $2 $timevalue`

我相信上述代码在它们自身方面都应该是有效的,但是,相同的输出似乎非常出乎意料:

1) 在输入密码后几乎同时执行命令 ssh 和 scp 因此,它没有给 localscript 足够的时间来完成它的工作,这是我看到的输出:

    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh  
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password: spawn /usr/bin/scp
username@1.2.3.4:"/home/some/file/*" /another/file/
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password:
scp: /home/some/file/*: No such file or directory

请注意:此功能在没有 expect 参与的情况下工作正常

2) 这里我们分别执行ssh和scp,但是好像无法识别localscript.sh这个文件的存在:

    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh  
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password:
bash: localscript.sh: No such file or directory
Warning private system unauthorized users will be prosecuted.
username@1.2.3.4's password:
scp: /home/some/file/*: No such file or directory

如有任何反馈,我将不胜感激,我认为第一种方法可能是一个可行的解决方案,除了 spawn 太快并且“ sleep ”或“之后”命令都没有帮助/工作的事实。我认为第二种方法也是有效的,但是在远程服务器上运行本地脚本的方式似乎与我们在 Linux 上使用“expect”时的常用方式不同。

抱歉说了这么多,我希望能尽快摆脱痛苦:)

最佳答案

实际上,您设置的超时没有像您期望的那样工作。两个脚本都生成了,每次生成后的 expect "assword:" 实际上是在捕获并响应相同的密码提示。

expect 实际上比粗略的一瞥会让您相信的更复杂。每个 spawn 都应该返回一个 PID,您可以将其与您的 expect 一起使用以查找特定进程的输出。

expect 也可以分解成多个部分,具有定义子程序的能力。这里有一些更高级的使用示例 https://wiki.tcl-lang.org/10045

在这种特定情况下,我建议等待 scp 完成,然后再生成下一个进程。

expect {
"assword:" {
send "$password\r"
exp_continue # Keep expecting
}
eof {
puts -nonewline "$expect_out(buffer)"
# eof so the process should be done
# It is safe to execute the next spawn
# without exp_continue this expect will
# break and continue to the next line
}
}

关于linux - 使用 expect 在远程机器上运行脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51990021/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com