期待脚本互动

时间:2017-07-05 22:47:14

标签: bash tcl expect suse

我有一个期望脚本,我想用它来检查SuSE服务器上的磁盘运行状况。 expect脚本将/将获取df -T|grep ext*|awk '{print $1}'的输出以生成ext2或3类型磁盘驱动器的列表。然后我可以接受该列表并迭代思考它,执行e2fsck -n $partitiondumpe2fs -h $partition

我在脚本上有一个开头,我省略了访问部分,因为这是直截了当的。

我遇到的问题是,只有在我生成期望脚本的服务器上存在分区文件(parts.txt)时,这才有效。我曾希望所有工作都可以在我登录的服务器上完成。

send_user "\nthese are the ext partitions on this element\n"
exp_send "df -T|grep ext*\|awk \'\{ print \$1 \}\' > parts.txt\r
expect "#"
set f [open "parts.txt" r]
while { [ gets $f part ] != -1} {
    exp_send "dumpe2fs -h $part\r"
    expect "#"
    exp_send "e2fsck -n $part\r"
    expect "#"
}
close $f
exp_send "exit\r"
expect {
    -re "~ #" {
        exp_send "exit\r"
    }
    -re ":~>" {
        exp_send "exit\r"
    }
}
expect eof

1 个答案:

答案 0 :(得分:0)

您需要将部件列表传输到本地端(即实际运行期望的系统),或者您需要将迭代移动到远程端。 如果我必须在两种方法之间做出选择,我可能会使用第一种选择;这将为复杂处理意外情况提供更多选择。

在本地获取列表

要在本地移动部件列表,我们调整您的脚本以便它运行df …命令并将输出写入我们可以看到它的位置,并使用更复杂的expect命令来处理输出

exp_send "df -T|grep ext*|awk '{ print \$1 }'\r"
set theParts {}
expect {
    -re {[^\s#]+} {
        lappend theParts $expect_out(0,string)
        exp_continue
    }
    "#" {
        # Just an empty script here
    }
}

这个expect会一次查找两个东西,但如果第一个找到一系列非空格非哈希字符,它会附加该序列(默认存储在该特定“字段”中)变量expect_out中的theParts数组的列表,等待。 (这是exp_continue的作用。)

既然您有一个列表,可以将其写入本地parts.txt,但为什么要打扰?也可以使用foreach直接遍历它:

foreach part $theParts {
    exp_send "dumpe2fs -h $part\r"
    expect "#"
    exp_send "e2fsck -n $part\r"
    expect "#"
}

远程移动循环

另一种方法是将循环放在另一台机器上。

exp_send "df -T|grep ext*|awk '{ print \$1 }' >parts.txt\r"
expect "#"
exp_send "for part in `cat parts.txt`; do dumpe2fs -h \$part || break; e2fsck -n \$part || break; done\r"
expect "#"

这是相当短的,但在上面的形式不是很强大。您可以制作健壮的shell脚本,但是如果您将shell脚本本身编写到远程文件上的文件中,则需要相当多的工作(并且很多更容易主持人然后从那里运行它。

为了您的理解,我上面已经完成的循环脚本是这样的(当分割多行并且没有Tcl的反斜杠时,这只是在Tcl元字符之前才真正需要的 - 在这个脚本中,这就是' s仅$

for part in `cat parts.txt`; do
    dumpe2fs -h $part || break
    e2fsck -n $part || break
done