代码之家  ›  专栏  ›  技术社区  ›  Zach Smith

如何在脚本执行期间向shell进程发送信号?

  •  1
  • Zach Smith  · 技术社区  · 6 年前

    我看到的大多数控制台应用程序教程都有编写控制台的概念。例如:

    C# => Console.WriteLine(...)
    node.js => console.log(...)
    ruby/python => print ...
    etc. etc.
    

    我知道,写入控制台基本上意味着写入stdout流,而且执行环境(即node.js或clr for c 35;)知道如何处理标准out=>写入终端屏幕本例。

    使用基于终端的脚本语言(我实际上需要在 .bat 脚本,但我也有兴趣知道如何使用 .sh 脚本),如何将子进程中的stdout保存到变量中?所以大致是这样的:

    script1Output=(first instance of stdout from script1)
    script2output=(first instance of stdout from script2)
    etc
    

    脚本1和脚本2是长时间运行的控制台应用程序。在启动脚本2之前,我需要等待一些数据缓存在脚本1中。

    1 回复  |  直到 6 年前
        1
  •  3
  •   rojo    6 年前

    CMD解释器使用 for /F 捕获和分析命令的输出。见 for /? 在CMD控制台中查看完整的详细信息。基本上,你会这样做:

    @echo off & setlocal
    
    for /f "usebackq delims=" %%I in (`cmd /c "child1.bat"`) do (
        echo(%%~I
        set "output=%%~I"
        setlocal enabledelayedexpansion
    
        rem # If !output! contains "Test String"...
        if not "!output!"=="!output:Test String=!" (
    
            rem # Do this to spawn child2.bat asynchronously
            start /b "" "child2.bat"
    
            rem # Or if you prefer child2.bat to block...
            rem # call "child2.bat"
        )
        endlocal
    )
    

    在.sh脚本中(可能是 #!/bin/bash 在顶部)可以更容易地将输出捕获到变量。

    output=$(command)
    echo $output
    

    但我猜那不是你想要的,因为 echo $output 从不开火直到 command 已经终止了,对吧?那样的话,也许你可以利用 awk 监视的输出 命令 并在检测到适当的输出时生成进程?

    # limit charset to optimize execution efficiency
    export LC_ALL=C
    
    bash -c ./child1.sh | awk '1;/Test String/ { system("(bash -c ./child2.sh) &") }'
    

    或者稍微复杂一点,您可以在纯bash中处理,而不依赖awk:

    export LC_ALL=C
    
    bash -c ./child1.sh | while IFS='' read -r line; do {
        echo $line
        [[ $line =~ "Test String" ]] && ./child2.sh &
    }; done