Bash脚本用于在几秒后重定向终端输出

huangapple go评论54阅读模式
英文:

Bash script to redirect avoid terminal output after few seconds

问题

我想编写一个脚本,它可以执行另一个bash脚本,然后在执行几秒钟后将脚本的输出重定向到终端之外的文件,以防止初始执行后将不必要的输出打印到屏幕上。

让我们将这个脚本命名为process.sh。我想编写类似以下的内容:

#!/bin/bash

process.sh & # 进程必须在后台运行,因为终端必须保持空闲以供其他进程使用

(sleep 5s
exec 1> cache_file) &

注意:上述脚本中有一些问题,可能需要根据你的需求进行调整,以确保它按预期工作。

英文:

I want to write a script which executes another bash script, and then redirects the script's output to the terminal after a few seconds of execution to a file instead, preventing unnecessary output being printed to the screen after initial execution.

Let's name the script process.sh. I want to write something like

!#/bin/bash

process.sh & # process will have to run in background 
             # since terminal has to be kept free for other processes

(sleep 5s
exec 1> cache_file) &

答案1

得分: 1

尝试这段经过 Shellcheck 清理的代码:

#!/bin/bash -p

kINIT_DURATION=5        # 秒
kOUTPUT_FILE=cache_file

./process.sh |  {
    start_time=$SECONDS
    init_end_time=$((start_time + kINIT_DURATION))
    while IFS= read -r line || [[ -n $line ]]; do
        printf '%s\n' "$line"
        if (( SECONDS > init_end_time )); then
            cat >"$kOUTPUT_FILE"
            exit
        fi
    done
}
  • 请查看 BashFAQ/001 (如何逐行(和/或逐字段)读取文件(数据流、变量)?) 以了解 while IFS= read -r line ... 循环的解释,该循环读取来自 process.sh 的输出,包括 [[ -n $line ]] 测试以处理可能未终止的最后一行输出。
  • 使用纯 Bash 代码逐行读取输入速度较慢,特别是当输入来自管道时(因为它必须逐字符读取以确保不读取行尾之外的字符)。如果 process.sh 生成大量输出,这段代码可能会太慢。
  • Bash 字符串无法包含 ASCII NUL 字符,因此如果 process.sh 生成包含它们的输出,该代码将无法正常工作。基本上,它只适用于文本,而不适用于二进制数据。
英文:

Try this Shellcheck-clean code:

#! /bin/bash -p

kINIT_DURATION=5        # seconds
kOUTPUT_FILE=cache_file

./process.sh |  {
                    start_time=$SECONDS
                    init_end_time=$((start_time + kINIT_DURATION))
                    while IFS= read -r line || [[ -n $line ]]; do
                        printf '%s\n' "$line"
                        if (( SECONDS > init_end_time )); then
                            cat >"$kOUTPUT_FILE"
                            exit
                        fi
                    done
                }
  • See BashFAQ/001 (How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?) for an explanation of the while IFS= read -r line ... loop that reads the output from process.sh, including the [[ -n $line ]] test to deal with a possibly unterminated final line of output.
  • Reading input line-by-line is slow with pure Bash code. It is particularly slow when input is from a pipeline (because it has to read character-by-character to ensure that it doesn't read past the ends of lines). This code may be too slow if process.sh generates a lot of output.
  • Bash strings can't hold ASCII NUL characters, so the code won't work if process.sh generates output that contains them. Essentially, it only works for text, not binary, data.

答案2

得分: 0

If you're happy to log all output, not just after 5 seconds:

#!/bin/bash

nohup process.sh </dev/null 1>out.log 2>err.log &

tail -n +1 -f out.log &
sleep 5
kill $!
英文:

If you're happy to log all output, not just after 5 seconds:

#!/bin/bash

nohup process.sh &lt;/dev/null 1&gt;out.log 2&gt;err.log &amp;

tail -n +1 -f out.log &amp;
sleep 5
kill $!

huangapple
  • 本文由 发表于 2023年6月5日 05:20:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76402459.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定