如何从程序中收集日志和输出并将它们传递到函数的参数中

时间:2019-07-01 10:39:19

标签: bash shell sh embedded-linux

我有一个Shell脚本,它具有Log语句功能

#!/bin/sh

Log() {
    echo $1 >> /some/logfile
}

Log "Test logging works"

这很好用!

接下来,我有一个用于记录语句的程序,如果我想从那里将​​日志添加到文件中,我可以这样做

SomeProgram >> SomeFile.txt

这也很棒!

但是,如果我想在同一外壳脚本中调用SomeProgram时将日志从Log传递到函数SomeProgram中,该怎么办。那可能吗?以下是我尝试的一些技巧,这些技巧无效。

Log "SomeProgram >> SomeFile.txt"
Log(SomeProgram >> SomeFile.txt)

问题
那么,如何才能从程序中收集日志并将其不断传递到函数的参数中?

环境:
Linux

3 个答案:

答案 0 :(得分:2)

如果是一次性案例,我会写一个循环。

SomeProgram | while IFS= read -r line; do
    Log "$line"
done

如果要执行很多操作,可以在Log中添加第二种模式,在该模式下,它从stdin读取而不是其参数。

Log() {
    case $1 in
        --stdin)
            while IFS= read -r line; do Log -- "$line"; done
            return;;

        --)
            shift;;
    esac

    echo "$*" >> /some/logfile
done
SomeProgram | Log --stdin

请勿check if stdin is a tty!这样做会导致Log()在您的脚本被非交互式调用时消耗stdin。好的脚本在自动化并在管道中使用时表现良好。他们不坚持使用键盘输入。

答案 1 :(得分:1)

您可以编写一个函数来处理标准输入以及任何参数:

Log() {
  # if STDIN (0) is not a terminal, iterate over any lines of standard input
  [[ ! -t 0 ]] && while read line; do echo "$line" >> /some/logfile; done

  # iterate over any arguments provided
  for arg; do echo "$arg" >> /some/logfile; done
}

如果您有一个将连续输出文本行的程序,则可以将该程序的标准输出通过管道|传递到函数的标准输入,手动输入参数或同时输入两者!

SomeProgram | Log
Log "line one" "line two"
SomeProgram | Log "additional line one" "additional line two"

检出man bash/^ *Compound Commands,以了解适用于函数的所有语法类型。

答案 2 :(得分:-1)

使用tee分割输出

Log "$(SomeProgram | tee -a SomeFile.txt)"

说明:

SomeProgram | tee将stdio输出从SomeProgram传递到tee命令

tee -a SomeFile.txt将输出到stdio,同时将-a添加到SomeFile.txt

Log "$(......)"将捕获括号内命令的标准输入并将结果作为参数传递给Log函数。