将stdout和stderr重定向到Function

时间:2012-08-10 15:33:40

标签: bash

我需要帮助将输出(stdin和stdout)从系统命令发送到bash函数,同时仍然接受来自参数的输入。类似下面的例子。有人能指出我走正确的道路吗?

LogMsg()
{
  DateTime=`date "+%Y/%m/%d %H:%M:%S"`
  echo '*****'$DateTime' ('$QMAKESPEC'): '$1 >> "$LogFile"
  echo $DateTime' ('$QMAKESPEC'): '$1
}

# Already works
LogMsg "This statement is sent directly"

# Wish I could do this:
# Capture both stdout & stderr of a system function to the logfile
# I do not presume that any of the syntax that follows is good
make 2>&1 >(LogMsg)

6 个答案:

答案 0 :(得分:13)

为此,您可以使用read bash builtin:

LogMsg()
{
  read IN # This reads a string from stdin and stores it in a variable called IN
  DateTime=`date "+%Y/%m/%d %H:%M:%S"`
  echo '*****'$DateTime' ('$QMAKESPEC'): '$IN >> "$LogFile"
  echo $DateTime' ('$QMAKESPEC'): '$IN
}

然后使用管道:

make 2>&1 | LogMsg

<强>更新

为了能够使用stdin或参数作为输入(根据chepner的评论),你可以这样做:

LogMsg()
{
  if [ -n "$1" ]
  then
      IN="$1"
  else
      read IN # This reads a string from stdin and stores it in a variable called IN
  fi

  DateTime=`date "+%Y/%m/%d %H:%M:%S"`
  echo '*****'$DateTime' ('$QMAKESPEC'): '$IN >> "$LogFile"
  echo $DateTime' ('$QMAKESPEC'): '$IN
}

答案 1 :(得分:1)

这是一个旧线程..但是我用它来帮助我编写一个日志函数,该函数还将输出多行命令输出:

<script>...</script>

答案 2 :(得分:0)

感谢发布回复的人。我想出了我的版本,它将为每条消息添加一次时间戳。

   g IDs V1 V2
1: 0 ID1  7 11
2: 1 ID1 13 18
3: 0 ID2  1  5
4: 1 ID2 17 19
5: 0 ID3  3  6
6: 1 ID3 13 21

答案 3 :(得分:0)

根据前面的答案,我整理了一些通用功能,无论有无日志文件都可以使用,如本文末尾所列。这些对于更复杂的脚本很方便。我通常将终端窗口消息打印到onready var camera2 = get_node("../ThirdPersonCamera") ,以免干扰可能需要重定向的合法程序输出。这些函数可以如下调用:

stderr

功能...

scriptFolder=$(cd $(dirname "$0") && pwd)
scriptName=$(basename $scriptFolder)
# Start a log file that will be used by the logging functions
logFileStart ${scriptName} "${scriptFolder)/${scriptName}.log"

# The following logs the message string passed to the function.
# - use a space for empty lines because otherwise the logging function
#   will hang waiting for input
logInfo " "
logInfo "Starting to do some work."

# The following will log each 'stdout` and `stderr` line piped to the function.
someOtherProgram 2>&1 | logInfo

答案 4 :(得分:-1)

在我看来,读取命令超时100ms(-t 0.1)将允许LogMsg处理输入管道和参数,而无需在没有输入的情况下永远等待。

function log(){ read -t 0.1 IN1
  echo $(date "+%Y/%m/%d %H:%M:%S")' ('$QMAKESPEC'): '$IN1 $* |tee -a $LogFile ;}
#test without, with pipe , with pipe and parameters , with parameters only
log ; echo foo | log ; echo foo | log bar ; log bar
2015/01/01 16:52:17 ():
2015/01/01 16:52:17 (): foo
2015/01/01 16:52:17 (): foo bar
2015/01/01 16:52:17 (): bar

tee -a复制到stdout并附加到$ LogFile

玩得开心

答案 5 :(得分:-2)

有两种方法, 首先,我认为更好的是创建一个bash文件并将结果传递给它:

make 2>&1 > ./LogMsg

第二种方法是将结果作为参数传递给函数:

LogMsg $(make 2>&1)