Linux 在 shell 脚本中使用 expect

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5174813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:05:51  来源:igfitidea点击:

use expect in shell script

linuxshellexpect

提问by user121196

I need to pass two arguments to expect, first one is the command to execute, the second one is the password.

我需要传递两个参数来期望,第一个是要执行的命令,第二个是密码。

here's my expect.sh

这是我的期望.sh

#!/usr/bin/expect
spawn [lrange $argv 0 0]
expect "password:"
send [lindex $argv 1]
interact

main script:

主要脚本:

./expect.sh "ssh root@$SERVER1"  $SERVER1_PASS

error:

错误:

couldn't execute "{ssh [email protected]}": no such file or directory
    while executing
"spawn [lrange $argv 0 0]"
    (file "./expect.sh" line 2)

why?

为什么?

采纳答案by Mikel

As far as I can tell, spawn's first argument needs to be a string, not a list of string.

据我所知,spawn 的第一个参数需要是一个字符串,而不是一个字符串列表。

And trying to pass a multi-word command line as a single string is going to cause problems. I think you'd have to split on spaces before calling spawn, and that's going to break if one argument contains a space. Maybe it's better to specify the password as the first argument, and the command as the rest of the arguments.

尝试将多字命令行作为单个字符串传递会导致问题。我认为你必须在调用 spawn 之前分割空格,如果一个参数包含空格,这将会中断。也许最好将密码指定为第一个参数,将命令指定为其余参数。

So try something like:

所以尝试这样的事情:

#!/usr/bin/expect
spawn [lindex $argv 1] [lrange $argv 2 end]
expect "password:"
send [lindex $argv 0]
interact

But then even that doesn't work.

但即使这样也行不通。

According to Re: expect - spawn fails with argument liston comp.lang.tcl (Google Groups version), we have to call evalto split the list.

根据Re:expect - spawn在 comp.lang.tcl(Google Groups 版本)上的参数列表失败,我们必须调用eval以拆分列表。

So the answer should be:

所以答案应该是:

#!/usr/bin/expect
eval spawn [lrange $argv 1 end]
expect "password:"
send [lindex $argv 0]
interact

Finally, you need to be sending Enter after the password, so you want:

最后,您需要在密码后发送 Enter,因此您需要:

#!/usr/bin/expect
eval spawn [lrange $argv 1 end]
expect "password:"
send [lindex $argv 0]
send '\r'
interact

And then switch the order and don't quote the command when calling it:

然后切换顺序,调用时不要引用命令:

./expect.sh "$SERVER1_PASS" ssh root@$SERVER1

But others have already done this. We don't need to re-invent the wheel.

但其他人已经这样做了。我们不需要重新发明轮子。

See e.g. expect ssh login script

参见例如expect ssh登录脚本

回答by user2131098

I found the shell scripts quite disturbing as far as scp was concerned. I decided to use php script for it, in crontab.

我发现就 scp 而言,shell 脚本非常令人不安。我决定在 crontab 中使用 php 脚本。

Php has a function

php有一个功能

$conn = ssh2_connect($scpServer, 22); 

then call

然后打电话

ssh2_auth_password($conn, $scpUser, $scpPassword);

ssh2_scp_send($conn, $scpLocalPath, $scpRemotePath);

OR

或者

ssh2_scp_recv($conn, $scpRemotePath, $scpLocalPath);

And u are done.

你已经完成了。

Of course you'll need to define the variables of user, password, and the rest

当然你需要定义用户、密码等变量

Though I advise you to create a linux user just for this purpose of scp.

尽管我建议您仅为 scp 的这个目的创建一个 linux 用户。

In order to install ssh2, try

为了安装 ssh2,请尝试