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

sti*_*ard 7 ssh bash terminal openvpn output

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

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

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

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

sudo openvpn --config FILE
Run Code Online (Sandbox Code Playgroud)

在另一个我运行:

ssh SERVER
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*pat 17

看起来你想在后台运行openvpn作为进程,同时在前台处理它的stdout.

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
Run Code Online (Sandbox Code Playgroud)

说明

让我们分成几块:

  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看到当前行以"Initialization Sequence Completed"结束,它就会退出(/ q部分)
  4. cat <&3 &
    • openvpn将继续写入文件描述符,3并最终阻止,如果没有从中读取
    • 为了防止这种情况,我们在后台运行cat来读取其余的输出

基本思想是openvpn在后台运行,但在某处捕获其输出,以便我们可以在前台运行一个命令,该命令将阻塞,直到它读取魔术词"初始化序列已完成".上面的代码尝试在不创建混乱的临时文件的情况下执行此操作,但更简单的方法可能只是使用临时文件.

  • 与此相关:我将如何停止原始后台进程(例如openvpn)? (2认同)