2

我有一个外部设备需要启动,然后等待它正常启动。我想要执行此操作的方法是通过串行端口(通过 Plink,它是 PuTTY 的命令行工具)连接到它并读取它打印的所有文本行并尝试找到表明它已启动的文本字符串适当地。找到该文本字符串后,脚本将继续执行。

问题是我需要实时阅读这些文本行。到目前为止,我只看到了调用命令并在命令完成后处理其输出的方法。或者,我可以通过将 & 附加到命令并将输出重定向到文件来让 Plink 在后台运行。但问题是这个文件从一开始就是空的,所以脚本将直接继续。有没有办法等待某个文件的新行并在它出现时读取它?或者有没有人有任何其他想法如何做到这一点?

这是迄今为止我找到的最佳解决方案:

./plink "connection_name" > new_file &

sleep 10 # Because I know that it will take a little while before the correct text string pops up but I don't know the exact time it will take...

while read -r line
do
    # If $line is the correct string, proceed
done < new_file

但是,我希望脚本在找到正确的文本字符串后直接继续。

所以,简而言之,有没有办法在命令完成执行之前连续访问命令的输出?

4

2 回答 2

7

这可能是您正在寻找的:

while read -r line; do
    # do your stuff here with $line
done < <(./plink "connection_name")

如果您需要sleep 10

{
    sleep 10
    while read -r line; do
        # do your stuff here with $line
    done
} < <(./plink "connection_name")

与以下相比,此解决方案的优势:

./plink "connection_name" | while read -r line; do
    # do stuff here with $line
done

(我相信很快有人会建议)是while循环不是在子shell中运行的。

该构造<( ... )称为Process Substitution

希望这可以帮助!

于 2013-07-09T10:29:55.550 回答
1

不要使用常规文件,而是使用命名管道。

mkfifo new_file

./plink "connection_name" > new_file &

while read -r line
do
    # If $line is the correct string, proceed
done < new_file

循环将while阻塞,直到有东西可以读取new_file,所以不需要休眠。

(这基本上是进程替换在幕后所做的,但不需要任何特殊的 shell 支持;POSIX shell 不支持进程替换。)

较新的版本bash(4.2 或更高版本)还支持允许管道的最终命令在当前 shell 中执行的选项,从而实现简单的解决方案

shopt +s lastpipe
./plink "connection_name" | while read -r line; do
    # ...
done

可能的。

于 2013-07-09T13:41:57.450 回答