bash序列:等待输出,然后启动下一个程序

时间:2014-01-08 16:29:31

标签: bash ssh terminal output openvpn

在我的情况下,我必须在ssh进入服务器之前运行openvpn,并且openvpn命令回显“初始化序列已完成”。

所以,我希望我的脚本设置openvpn,然后设置ssh。

我的问题是:你如何在后台执行bash命令并等待它在运行另一个程序之前回显“已完成”?

我目前的做法是打开2个终端窗格,其中一个正在运行:

sudo openvpn --config FILE

在另一个我跑:

ssh SERVER

一旦第一个终端窗格显示“初始化序列已完成”文本。

2 个答案:

答案 0 :(得分:16)

好像你想要run openvpn as a process in the background while processing its stdout in the foreground

exec 3< <(sudo openvpn --config FILE)
sed '/Initialization Sequence Completed$/q' <&3 ; cat <&3 &
# VPN initialization is now complete and running in the background
ssh SERVER

说明

让我们把它分成几部分:

  1. echo <(sudo openvpn --config FILE)会打印出/dev/fd63之类的内容
    • <(..)在后​​台运行 openvpn ,并且......
    • 将其stdout附加到文件描述符,该描述符由echo
    • 打印出来
  2. exec 3< /dev/fd63
    • (其中 / dev / fd63 是从步骤1打印的文件描述符)
    • 这告诉shell打开文件描述符( / dev / fd63 )进行阅读,然后......
    • 在文件描述符3
    • 中使其可用
  3. sed '/Initialization Sequence Completed$/q' <&3
    • 现在我们在前台运行 sed ,但是从我们刚刚打开的文件描述符3中读取它
    • 一旦 sed 看到当前行以“初始化序列已完成”结束,它就会退出( / q 部分)
  4. cat <&3 &
    • openvpn 将继续写入文件描述符3并最终阻止,如果没有任何内容读取
    • 为了防止这种情况,我们在后台运行 cat 来读取输出的其余部分
  5. 基本思想是在后台运行openvpn,但在某处捕获其输出,以便我们可以在前台运行一个命令,直到它读取魔术词“初始化序列已完成”。上面的代码尝试在不创建混乱的临时文件的情况下执行此操作,但更简单的方法可能只是使用临时文件。

答案 1 :(得分:1)

在grep中使用-m 1--line-buffered在连续流中的第一次匹配后终止grep。这应该有效:

sudo openvpn --config FILE | grep -m "Initialization Sequence Completed" --line-buffered && ssh SERVER