如何从shell读取命令中返回的shell"read"命令返回? [英] How to return from shell 'read' command passed in expect script?

查看:389
本文介绍了如何从shell读取命令中返回的shell"read"命令返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很不熟悉使用Expect,并且对将命令传递给Expect脚本有点困惑,所以请耐心等待...我已经搜索了很多论坛,但似乎找不到找到使用期望脚本的示例.读取命令以获取用户输入.

I am really new to using expect, and a bit confused regarding passing commands to an expect script, so please bear with me... I have searched numerous forums, but cannot seem to find an example of an expect script that uses the read command to get user input.

在我的Korn Shell脚本中,我调用Expect脚本(expectssh.exp)ssh登录到另一台主机,并获得有关该主机的网络配置(网络接口卡号和子网掩码信息)的用户输入.我将四个参数传递给Expect脚本:远程主机ip地址,用户名,密码和要运行的命令列表.我的期望脚本如下:

In my Korn shell script, I call an expect script (expectssh.exp) to ssh login to another host and get user input regarding that host's network configuration (network interface card number and subnet mask information). I pass four arguments to the expect script: the remote host ip address, the username, the password, and the list of commands to run. My expect script is below:

#!/usr/bin/expect
# Usage: expectssh <host> <ssh user> <ssh password> <script>

set timeout 60
set prompt "(%|#|\\$) $"
set commands [lindex $argv 3];

spawn ssh [lindex $argv 1]@[lindex $argv 0]

expect {
"*assword:" { 
send -- "[lindex $argv 2]\r" 
expect -re "$prompt"
send -- "$commands\r" 
}

"you sure you want to continue connecting" {
send -- "yes\r"
expect "*assword:"
send -- "[lindex $argv 2]\r"
expect -re "$prompt"
send -- "$commands\r" 
}

timeout {
exit }
}

该脚本运行良好,除了在进入"read"命令时,该脚本在用户按下Enter之后不会继续或退出.它只是挂了.

The script runs well, except that when it gets to the 'read' command, the script does not continue or exit after the user presses enter. It just hangs.

我传递给Expect脚本的命令及其调用如下:

The commands I pass to the expect script and its call are as follows:

SCRIPT='hostname > response.txt;netstat -rn;read net_card?"What is the network interface card number?   " >> response.txt; read net_mask?"What is the subnet mask? " >> response.txt'

/usr/bin/expect ./expectssh.exp $hostip $usr $pswd "$SCRIPT"

关于如何在我的期望脚本中传递read命令而不挂起的任何建议?

Any suggestions on how I can pass the read command through my expect script without it hanging?

在旁注中,因为我知道它会出现-我不允许进行基于密钥的自动SSH登录.我必须提示输入用户名和密码,这是通过调用此期望脚本的Korn Shell脚本完成的.

On a side note because I know it will come up - I am not allowed to do key-based automatic SSH login. I have to prompt for a username and password, which is done from the Korn shell script that calls this expect script.

感谢您的任何建议和帮助!

Thanks for any suggestions and help you can provide!

推荐答案

对于感兴趣的任何人,我都可以通过做一些事情来获得read命令用于用户输入:

For anyone interested, I was able to get the read command to work for user input by doing a few things:

(1)将其放在-re $prompt块中,而不是在密码输入之后附加send -- "$commands\r".

(1) Putting it within an -re $prompt block instead of appending send -- "$commands\r" after the password entry.

(2)将命令硬编码到脚本中,而不是将它们传递进来.

(2) Hard coding the commands into the script rather than passing them in.

(3)在命令后加上interact语句,以便在用户响应之前不输入下一个发送命令.

(3) Following the command with an interact statement so that the next send command isn't entered before the user responds.

我的期望块现在看起来像这样:

My expect block now looks like this:

expect {
    -re "(.*)assword:" { 
        send -s "$pswd\r" 
        exp_continue
    }
    "denied, please try again" {
        send_user "Invalid password or account.\n"
        exit 5
    }
    "incorrect" {
        send_user "Invalid password or account.\n"
        exit 5
    }
    "you sure you want to continue connecting" {
        send -s "yes\r"
        exp_continue
    }
    -re $prompt {
        set timeout -1
        send -- "hostname > partnerinit\r"
        expect -exact "hostname > partnerinit\r"
        send -s "netstat -rn\r"
        expect -re "$prompt"
        send -- "read n_card?'Enter the network interface card number for this server (i.e. eth0):  '\r"
        interact "\r" return
        send -- "\r"
        send -- "echo \$n_card >> partnerinit\r"
        send -- "msk=\$(cat /etc/sysconfig/network-scripts/ifcfg-\$n_card | grep NETMASK)\r"
        send -- "msk=\$(echo \${msk#NETMASK=})\r"
        send -- "echo \$msk >> partnerinit\r"
        send -- "cat partnerinit\r"
        set retval 0
    }
    timeout {
        send_user "Connection to host $host timed out.\n"
        exit 10
    }
    eof {
        send_user "Connection to host $host failed.\n"
        exit 1
    }
}

我还更新了脚本,以根据用户输入的网络接口卡号自动确定子网掩码.引起我注意的是,在具有多个接口卡的盒子中,很难自动找到网络接口卡号.最好从小处开始,让用户输入它,然后在整个脚本运行后对其进行微调/自动化.

I also updated the script to automatically determine the subnet mask based on the network interface card number entered by the user. It was brought to my attention that finding the network interface card number would be very difficult to automate in the case of a box that has multiple interface cards. Better to start small and have the user enter it and fine-tune/automate it later once the overall script is working.

现在,我正在进行修改,以将我的partnerinit文件返回我的本地主机,并从每个预期条件中返回有意义的退出状态.

Now I'm working on modifying this to scp my partnerinit file back to my local host and to return meaningful exit statuses from each of the expect conditions.

这篇关于如何从shell读取命令中返回的shell"read"命令返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆