如何等待进程的某些输出然后在 Bash 中继续?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7197527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:58:17  来源:igfitidea点击:

How can I wait for certain output from a process then continue in Bash?

bash

提问by Brad

I'm trying to write a bash script to do some stuff, start a process, wait for that process to say it's ready, and then do more stuff while that process continues to run. The issue I'm running into is finding a way to wait for that process to be ready before continuing, and allowing it to continue to run.

我正在尝试编写一个 bash 脚本来做一些事情,启动一个进程,等待该进程说它准备好了,然后在该进程继续运行时做更多的事情。我遇到的问题是找到一种方法在继续之前等待该进程准备就绪,并允许它继续运行。

In my specific case I'm trying to setup a PPP connection. I need to wait until it has connected before I run the next command. I would also like to stop the script if PPP fails to connect. pppd prints to stdout.

在我的特定情况下,我正在尝试设置 PPP 连接。我需要等到它连接后才能运行下一个命令。如果 PPP 连接失败,我还想停止脚本。pppd 打印到标准输出。

In psuedo code what I want to do is:

在伪代码中,我想做的是:

[some stuff]
echo START

[set up the ppp connection]
pppd <options> /dev/ttyUSB0
while 1
  if output of pppd contains "Script /etc/ppp/ipv6-up finished (pid ####), status = 0x0"
    break
  if output of pppd contains "Sending requests timed out"
    exit 1

[more stuff, and pppd continues to run]
echo CONTINUING

Any ideas on how to do this?

关于如何做到这一点的任何想法?

回答by Ivin

I had to do something similar waiting for a line in /var/log/syslog to appear. This is what worked for me:

我不得不做类似的事情,等待 /var/log/syslog 中的一行出现。这对我有用:

FILE_TO_WATCH=/var/log/syslog
SEARCH_PATTERN='file system mounted'

tail -f -n0 ${FILE_TO_WATCH} | grep -qe ${SEARCH_PATTERN}

if [ $? == 1 ]; then
    echo "Search terminated without finding the pattern"
fi

It pipes all new lines appended to the watched file to grep and instructs grep to exit quietly as soon as the pattern is discovered. The following if statement detects if the 'wait' terminated without finding the pattern.

它将所有附加到监视文件的新行通过管道传递给 grep,并在发现模式后立即指示 grep 安静地退出。下面的 if 语句检测“等待”是否在没有找到模式的情况下终止。

回答by sblom

There's a tool called "Expect" that does almost exactly what you want. More info: http://en.wikipedia.org/wiki/Expect

有一个名为“Expect”的工具几乎可以满足您的需求。更多信息:http: //en.wikipedia.org/wiki/Expect

You might also take a look at the man pages for "chat", which is a pppd feature that does some of the stuff that expect can do.

您还可以查看“chat”的手册页,这是一个 pppd 功能,可以完成一些预期可以做的事情。

回答by Brad

The quickest solution I came up with was to run pppd with nohup in the background and check the nobup.out file for stdout. It ended up something like this:

我想出的最快的解决方案是在后台运行带有 nohup 的 pppd 并检查 nobup.out 文件中的 stdout。结果是这样的:

sudo nohup pppd [options] 2> /dev/null &
#  check to see if it started correctly
PPP_RESULT="unknown"
while true; do
  if [[ $PPP_RESULT != "unknown" ]]; then
    break
  fi
  sleep 1
  # read in the file containing the std out of the pppd command
  #  and look for the lines that tell us what happened
  while read line; do
    if [[ $line == Script\ /etc/ppp/ipv6-up\ finished* ]]; then
      echo "pppd has been successfully started"
      PPP_RESULT="success"
      break
    elif [[ $line == LCP:\ timeout\ sending\ Config-Requests ]]; then
      echo "pppd was unable to connect"
      PPP_RESULT="failed"
      break
    elif [[ $line == *is\ locked\ by\ pid* ]]; then
      echo "pppd is already running and has locked the serial port."
      PPP_RESULT="running"
      break;
    fi
  done < <( sudo cat ./nohup.out )
done

回答by dimba

If you go with expect, as @sblom advised, please check autoexpect.

如果您expect按照@sblom 的建议使用 ,请检查autoexpect

You run what you need via autoexpectcommand and it will create expectscript. Check man pagefor examples.

你通过autoexpect命令运行你需要的东西,它会创建expect脚本。检查手册页以获取示例。

回答by Swapnil jaiswal

Sorry for the late response but a simpler way would to use wait. waitis a BASH built-in command which waits for a process to finish

抱歉回复晚了,但更简单的方法是使用等待。 wait是一个 BASH 内置命令,它等待一个进程完成

Following is the excerpt from the MAN page.

以下是 MAN 页面的摘录。

  wait [n ...]
        Wait  for each specified process and return its termination sta-
        tus.  Each n may be a process ID or a job  specification;  if  a
        job  spec  is  given,  all  processes in that job's pipeline are
        waited for.  If n is not given, all currently active child  pro-
        cesses  are  waited  for,  and  the return status is zero.  If n
        specifies a non-existent process or job, the  return  status  is
        127.   Otherwise,  the  return  status is the exit status of the
        last process or job waited for.

For further reference on usage: Refer to wiki page

有关用法的进一步参考: 请参阅维基页面