Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.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/TCL脚本已损坏_Bash_Tcl_Expect - Fatal编程技术网

Bash expect/TCL脚本已损坏

Bash expect/TCL脚本已损坏,bash,tcl,expect,Bash,Tcl,Expect,我有一个Bash脚本,它在一个单独的函数中包含一个expect/TCL EOF脚本。expect脚本退出时可能有0-4个退出代码,这取决于expect/TCL脚本从远程设备确定的内容,并且在if。。。埃利夫。。。else语句我根据expect/TCL函数中的退出代码向变量写入特定字符串。然后将控制传递回Bash脚本,其中case块在所述变量包含的字符串上运行 我遇到的问题是,我的Bash函数(包含expect/TCL脚本)没有很好地捕获退出代码3,因为我可以看到日志文件条目正确写入日志文件,但是

我有一个Bash脚本,它在一个单独的函数中包含一个expect/TCL EOF脚本。expect脚本退出时可能有0-4个退出代码,这取决于expect/TCL脚本从远程设备确定的内容,并且在if。。。埃利夫。。。else语句我根据expect/TCL函数中的退出代码向变量写入特定字符串。然后将控制传递回Bash脚本,其中case块在所述变量包含的字符串上运行

我遇到的问题是,我的Bash函数(包含expect/TCL脚本)没有很好地捕获退出代码3,因为我可以看到日志文件条目正确写入日志文件,但是如果我回显退出代码的值,当情况应该是3时,它实际上捕捉到一个零,因此我的case语句没有准确地切换

你能找到窃听器吗

为了保持文章的简洁性和具体性,我将脚本切分为以下几个部分,因此假设周围的代码运行正常

function myTclFunc()
{
    /usr/bin/expect<<EOF
    proc log_msg {msg {to_stdout no}} {
        set log_line "[timestamp -format {[%d/%m/%Y @ %T]}] \$msg"
        set fh [open ~/mylogfile.log a]
        puts \$fh \$log_line
        close \$fh
        if {\$to_stdout} {puts \$log_line}
    }

    ;#exp_internal 1
    set timeout 5
    set send_human {.1 .3 1 .05 2}

    spawn ssh -o "StrictHostKeyChecking no" "[USER]@$1"

    expect {
        "password: " { send -h "[MY_PASSWD]\r" }
        timeout { log_msg "A RELEVANT STRING TO LOG $1 / $2"; exit 1 }
    }

    set timeout 3
    sleep 1 ;
    send -h "[COMMAND A]\r" ;
    expect {
        timeout { exit 1 }
        -re {\m\d{1,}(\.\d{1,}){3}\M}
    }
    if { ! [regexp {192\.[0-9]{1,3}\.{2}[0-9]{1,3}} $expect_out(0,string)]} {
        send -h "[COMMAND B]\r" ;
    }
    expect {
        "[STRING 1]" { 
            send -h "[COMMAND C]\r" ;
            log_msg "Problem F on $1 / $2" ;
            exit 3
        }
        "[STRING 2]" { 
            send -h "[COMMAND D]\r" ;
            sleep 1 ;
            send -h "[COMMAND E]\r" ;
            send -h "\r" ;
            puts "\r"
            ;#exit 0
        }
    }
    expect eof
EOF
    if [[ $? -eq 0 ]]; then
        passBack="GOOD";
    elif [[ $? -eq 3 ]]; then
        passBack="BAD";
    else
        passBack="TIMEOUT";
    fi;
}

[...snipped code...]
myTclFunc $myVar $1

case "$passBack" in
GOOD)
    echo ""
    exit 0
    ;;
BAD)
    echo ""
    exit 4
    ;;
CHECK)
    echo ""
    exit 3
    ;;
esac;
[...snipped code...]

壳牌和Tcl的混合有时会有点棘手。特别是,您希望将\传递到正则表达式引擎中的一些位置,在带有不带引号分隔符的here文档中。幸运的是,你把REs放在括号里,所以它只是让人困惑,而不是超级困惑

bash文档的相关部分说明:

这里有文件 这种类型的重定向指示shell从当前源读取输入,直到看到一行只包含单词,没有尾随空格。然后,读取到该点的所有行将用作命令的标准输入

此处文件的格式为:

   <<[-]word
       here-document
   delimiter
哦,在整个脚本中,您还需要\\r如上所述,而不是\r

我认为将脚本分成两个文件会更容易,一个只是Bash代码,另一个只是Tcl代码,至少在您开发它时是这样。这样,你就可以使事情顺利进行,而不必在引用的许多层面上大惊小怪。现在替换的内容可以作为参数传递给脚本

将所有内容重新打包时,bash的printf%q可能会有所帮助。它会产生一些难以阅读的内容,但毕竟这是一个打包操作

关于错误代码呢?那里的问题更简单;测试本身-[$?-eq 0]]-设置错误代码。您必须将其保存到适当的变量中,然后根据该变量进行测试

在这里,检查这些简化的案例:

bash-3.2$ ( exit 2 ); if [[ $? -eq 0 ]]; then echo ok; elif [[ $? -eq 2 ]]; then echo good; else echo bad; fi
bad
bash-3.2$ ( exit 2 ); echo $?; if [[ $? -eq 0 ]]; then echo ok; elif [[ $? -eq 2 ]]; then echo good; else echo bad; fi
2
ok
bash-3.2$ ( exit 2 ); code=$?; echo $code; if [[ $code -eq 0 ]]; then echo ok; elif [[ $code -eq 2 ]]; then echo good; else echo bad; fi
2
good

第一个是你现在正在做的事情,第二个显示了它是多么的不明显——插入的回声改变了结果——第三个显示了如何处理它——在这里将值存储在代码中,但名称并不是那么特别。

有用,虽然不幸的是,我仍然看到退出代码3没有被捕获的问题。@junky叔叔哈;经典的bash问题。你还需要解决其他问题……啊,我明白了。我很惊讶我在奥雷利的书《Shell脚本》中没有包括这个。。。谢谢,我将进行测试。我将确保从ssh会话中退出条件“3”和可能的“2”,以便您从脚本中获得返回代码,而不是ssh会话。因此,换句话说,如果登录,请确保您的expect脚本向远程计算机发送退出\n\r。不过,我已经处理了这个问题。
bash-3.2$ ( exit 2 ); if [[ $? -eq 0 ]]; then echo ok; elif [[ $? -eq 2 ]]; then echo good; else echo bad; fi
bad
bash-3.2$ ( exit 2 ); echo $?; if [[ $? -eq 0 ]]; then echo ok; elif [[ $? -eq 2 ]]; then echo good; else echo bad; fi
2
ok
bash-3.2$ ( exit 2 ); code=$?; echo $code; if [[ $code -eq 0 ]]; then echo ok; elif [[ $code -eq 2 ]]; then echo good; else echo bad; fi
2
good