Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 无法向远程主机执行多个expect send语句_Bash_Expect - Fatal编程技术网

Bash 无法向远程主机执行多个expect send语句

Bash 无法向远程主机执行多个expect send语句,bash,expect,Bash,Expect,我需要使用expect在远程PC上编辑/etc/host文件。 以下是代码部分: /usr/bin/expect << EOD set timeout 10 set send_slow { 1 .01 } spawn -noecho ssh -o StrictHostKeyChecking=no -o CheckHostIP=no -o ConnectTimeout=10 ${USRNAME}@${REMOTE_PC} expect {

我需要使用expect在远程PC上编辑/etc/host文件。 以下是代码部分:

/usr/bin/expect << EOD
    set timeout 10
    set send_slow { 1 .01 }

    spawn -noecho ssh -o StrictHostKeyChecking=no -o CheckHostIP=no -o ConnectTimeout=10 ${USRNAME}@${REMOTE_PC}
    expect  {
        timeout                 { send_user "\nTimeout while oonnecting to ${REMOTE_PC}\n"; exit }
        "*No route to host*"    { send_user "\n${REMOTE_PC} not reachable\n"; exit }
        "*assword: "            { send -s "$PASSWORD\r\r" }
    }
    expect  {
        timeout { send_user "\nTimeout waiting for prompt\n"; exit }
        # "$PS1" refers to the system prompt setup in .bash_profile.
        "$PS1"  {
            send -s "(grep -xq -P '${MY_SVR_IP}\tcm' /etc/hosts) && echo __CM_FOUND || echo __CM_NOTFOUND\r"
            expect {
                # Order is IMPORTANT! __NOTFOUND must comes first.
                __CM_NOTFOUND  {
                    send_user "\nNot Found!\n";
                    send -s "sudo sed -i -r '/127.0.0.1 +Local_Host/i # Modified on ${MOD_DATE}.' /etc/hosts \r";
                    send -s "sudo sed -i -r 's/(127.0.0.1 +Local_Host)/#\1/g' /etc/hosts \r";
                    send -s "sudo sed -i -r 's/(127.0.0.1 +cm)/#\1/g' /etc/hosts \r";
                    send -s "sudo sed -i -r '/\#127.0.0.1 +cm/a ${MY_SVR_IP}\tcm' /etc/hosts \r";
                    send "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts\r";
                    send_user "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts \r";
                    send -s "exit\r"
                }
                # Do nothing, if found. NOTE: Cannot put any comments after end brace.
                __CM_FOUND     { send -s "exit\r" }
            }
        }
    }
EOD
但不会执行后续行。 为什么?

感谢您提前提出建议。谢谢

#=============================================================

我将脚本修改为:

/usr/bin/expect -d << EOD
    set timeout 3
    set send_slow { 1 .01 }
    set prompt_re {*${USERNAME}@${REMOTE_PC}:*\$ $}
    spawn -noecho ssh -o StrictHostKeyChecking=no -o CheckHostIP=no -o ConnectTimeout=3 ${USERNAME}@${REMOTE_PC}
    expect  {
        timeout                 { send_user "\nTimeout while oonnecting to ${REMOTE_PC}\n"; exit }
        "*No route to host*"    { send_user "\n${REMOTE_PC} not reachable\n"; exit }
        "*assword: "            { send -s "$PASSWORD\r\r" }
    }
    expect  {
        timeout { send_user "\nTimeout waiting for prompt\n"; exit }
        -re "$prompt_re" {
            send_user "\nSuccessfully login to ${REMOTE_PC}.\n"
        }
    }
    send -s "(grep -xq -P '${MY_SVR_IP}\tcm' /etc/hosts) && echo __CM_FOUND || echo __CM_NOTFOUND\r"
    expect {
        __CM_NOTFOUND  {
            send_user "\nNot Found!\n";
            send -s { "sudo sed -i -r '/127.0.0.1 +Local_Host/i # Modified on ${MOD_DATE}.' /etc/hosts \r" }
            send -s { "sudo sed -i -r 's/(127.0.0.1 +Local_Host)/#\1/g' /etc/hosts \r" }
            send -s { "sudo sed -i -r 's/(127.0.0.1 +cm)/#\1/g' /etc/hosts \r" }
            send -s { "sudo sed -i -r '/\#127.0.0.1 +cm/a ${MY_SVR_IP}\tcm' /etc/hosts \r" }
            send_user "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts \r"
            send -s "exit\r"
        }
        __CM_FOUND     { send -s "exit\r" }
    }
EOD

PS1
将仅存在于交互式shell中

在调试输出中是否看到以下内容

send:将“密码\r\r”发送到{exp4}
expect:“(spawn_id exp4)是否与全局模式”匹配?
这个空字符串是$PS1

不幸的是,处理提示的惯用方法是以正则表达式模式对其进行硬编码:

# This is the patten to match a prompt on the remote host, alter as needed.
# This matches a dollar sign and a space at the end of the prompt 
set prompt_re {\$ $}
我发现避免深度嵌套的expect命令有助于提高可读性:

spawn -noecho ssh -o StrictHostKeyChecking=no -o CheckHostIP=no -o ConnectTimeout=10 ${USRNAME}@${REMOTE_PC}
expect  {
    timeout                 { send_user "\nTimeout while oonnecting to ${REMOTE_PC}\n"; exit }
    "*No route to host*"    { send_user "\n${REMOTE_PC} not reachable\n"; exit }
    "*assword: "
}
send -s "$PASSWORD\r\r"
expect  {
    timeout { send_user "\nTimeout waiting for prompt\n"; exit }
    -re $prompt_re
}
send -s "(grep -xq -P '${MY_SVR_IP}\tcm' /etc/hosts) && echo __CM_FOUND || echo __CM_NOTFOUND\r"
expect {
    __CM_NOTFOUND  {
        # Order is IMPORTANT! __NOTFOUND must comes first.
        send_user "\nNot Found!\n";
        send -s "sudo sed -i -r '/127.0.0.1 +Local_Host/i # Modified on ${MOD_DATE}.' /etc/hosts \r";
        send -s "sudo sed -i -r 's/(127.0.0.1 +Local_Host)/#\1/g' /etc/hosts \r";
        send -s "sudo sed -i -r 's/(127.0.0.1 +cm)/#\1/g' /etc/hosts \r";
        send -s "sudo sed -i -r '/\#127.0.0.1 +cm/a ${MY_SVR_IP}\tcm' /etc/hosts \r";
        send "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts\r";
        send_user "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts \r";
        send -s "exit\r"
    }
    __CM_FOUND     {
        # Do nothing, if found. NOTE: Cannot put any comments after end brace.
        send -s "exit\r"
    }
}

注意不要像这样将注释放在expect块中:expect将把它们视为模式操作对。Expect将看到Expect命令行:

    expect  {
        timeout { send_user "\nTimeout waiting for prompt\n"; exit }
        {#}     {"$PS1"}
        refers  {to}
        the     {system}
        prompt  {setup}
        in      {.bash_profile.}
        "$PS1"  {
            send -s "(grep -xq -P '${MY_SVR_IP}\tcm' /etc/hosts) && echo __CM_FOUND || echo __CM_NOTFOUND\r"
            expect {
                {#}            {Order}
                is             {IMPORTANT!}
                __NOTFOUND     {must}
                comes          {first.}
                __CM_NOTFOUND  {
                    send_user "\nNot Found!\n";
                    send -s "sudo sed -i -r '/127.0.0.1 +Local_Host/i # Modified on ${MOD_DATE}.' /etc/hosts \r";
                    send -s "sudo sed -i -r 's/(127.0.0.1 +Local_Host)/#\1/g' /etc/hosts \r";
                    send -s "sudo sed -i -r 's/(127.0.0.1 +cm)/#\1/g' /etc/hosts \r";
                    send -s "sudo sed -i -r '/\#127.0.0.1 +cm/a ${MY_SVR_IP}\tcm' /etc/hosts \r";
                    send "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts\r";
                    send_user "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts \r";
                    send -s "exit\r"
                }
                {#}                   {Do}
                nothing,              {if}
                found.                {NOTE:}
                Cannot                {put}
                any                   {comments}
                after                 {end}
                brace.                {__CM_FOUND}
                { send -s "exit\r" }
            }
        }
    }

使用
expect-d后使用
expect-d(expect:does“\r\n”((spawn\u id exp4)匹配glob模式“\uuuu CM\u NOTFOUND”?no“\uu CM\u FOUND”?不欢迎使用Ubuntu 16.04.6 LTS(GNU/Linux 4.4.15-uno1483-rt23+i686)*文档:*管理:*支持:上次登录:Tue May 25 18:55:15 2021 expect:does”\r\n(\r\n欢迎访问Ubuntu 16.04.6 LTS(GNU/Linux 4.4.15-uno1483-rt23+i686)\r\n\r\n*文档:\r\n*管理:\r\n*支持:\r\n\r\n上次登录:Tue May 25 18:55:15 2021“(生成id exp4)匹配全局模式“\u CM\u未找到”?否“\u CM\u未找到”?否[support@agv0001:~]$ [support@agv0001:~]$(grep-xq-P'cm'/etc/hosts)&&echo_uuucm_FOUND | echo uu CM_NOTFOUND uu CM_NOTFOUND尝试在每次
发送后添加一个
expect
等待shell提示,否则您可能发送得太快。将expect想象为一个人,他只会在看到下一个shell提示后发送新命令。是否存在打字错误?是否应该是
-re$prompt\re
?是的,q你说得对。
spawn -noecho ssh -o StrictHostKeyChecking=no -o CheckHostIP=no -o ConnectTimeout=10 ${USRNAME}@${REMOTE_PC}
expect  {
    timeout                 { send_user "\nTimeout while oonnecting to ${REMOTE_PC}\n"; exit }
    "*No route to host*"    { send_user "\n${REMOTE_PC} not reachable\n"; exit }
    "*assword: "
}
send -s "$PASSWORD\r\r"
expect  {
    timeout { send_user "\nTimeout waiting for prompt\n"; exit }
    -re $prompt_re
}
send -s "(grep -xq -P '${MY_SVR_IP}\tcm' /etc/hosts) && echo __CM_FOUND || echo __CM_NOTFOUND\r"
expect {
    __CM_NOTFOUND  {
        # Order is IMPORTANT! __NOTFOUND must comes first.
        send_user "\nNot Found!\n";
        send -s "sudo sed -i -r '/127.0.0.1 +Local_Host/i # Modified on ${MOD_DATE}.' /etc/hosts \r";
        send -s "sudo sed -i -r 's/(127.0.0.1 +Local_Host)/#\1/g' /etc/hosts \r";
        send -s "sudo sed -i -r 's/(127.0.0.1 +cm)/#\1/g' /etc/hosts \r";
        send -s "sudo sed -i -r '/\#127.0.0.1 +cm/a ${MY_SVR_IP}\tcm' /etc/hosts \r";
        send "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts\r";
        send_user "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts \r";
        send -s "exit\r"
    }
    __CM_FOUND     {
        # Do nothing, if found. NOTE: Cannot put any comments after end brace.
        send -s "exit\r"
    }
}
    expect  {
        timeout { send_user "\nTimeout waiting for prompt\n"; exit }
        {#}     {"$PS1"}
        refers  {to}
        the     {system}
        prompt  {setup}
        in      {.bash_profile.}
        "$PS1"  {
            send -s "(grep -xq -P '${MY_SVR_IP}\tcm' /etc/hosts) && echo __CM_FOUND || echo __CM_NOTFOUND\r"
            expect {
                {#}            {Order}
                is             {IMPORTANT!}
                __NOTFOUND     {must}
                comes          {first.}
                __CM_NOTFOUND  {
                    send_user "\nNot Found!\n";
                    send -s "sudo sed -i -r '/127.0.0.1 +Local_Host/i # Modified on ${MOD_DATE}.' /etc/hosts \r";
                    send -s "sudo sed -i -r 's/(127.0.0.1 +Local_Host)/#\1/g' /etc/hosts \r";
                    send -s "sudo sed -i -r 's/(127.0.0.1 +cm)/#\1/g' /etc/hosts \r";
                    send -s "sudo sed -i -r '/\#127.0.0.1 +cm/a ${MY_SVR_IP}\tcm' /etc/hosts \r";
                    send "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts\r";
                    send_user "grep -B3 -A2 -P '${MY_SVR_IP}\tcm' /etc/hosts \r";
                    send -s "exit\r"
                }
                {#}                   {Do}
                nothing,              {if}
                found.                {NOTE:}
                Cannot                {put}
                any                   {comments}
                after                 {end}
                brace.                {__CM_FOUND}
                { send -s "exit\r" }
            }
        }
    }