【问题标题】:How to redirect STDOUT and STDERR in a file for every command? [duplicate]如何为每个命令在文件中重定向 STDOUT 和 STDERR? [复制]
【发布时间】:2020-02-11 22:48:18
【问题描述】:

我正在尝试将来自终端的 STDOUT 和 STDERR(如果可能的话,用户提供的 STDIN)存储在每个命令的文件中。

所以我开始创建一个陷阱函数,以编辑的方式执行每个命令,例如:

shopt -s extdebug

preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND

    eval `history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"` |& tee ~/recent_output.txt
    return 1 # This prevent executing of original command
}
trap 'preexec_invoke_exec' DEBUG


并保存上述文件并执行

source file.sh

这完成了我想要的工作,但阻止了一些命令的执行

cd ..

这样做的原因是管道创建了一个子 shell,然后执行其中的每个命令。所以主壳不受影响。

甚至是 bash 的脚本功能,即

script ~/recent_output.txt

工作但仅在您在终端中执行exit 后才给出输出

所以,基本上我想存储/获取在 bash 终端中执行的上一个命令的输出。你可以用任何语言帮助我(golang、python...)。

【问题讨论】:

  • "eval `history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`" 为什么要 eval?
  • 因为history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"输出了一个字符串,eval可以执行
  • 为什么不直接使用script?我担心eval 在处理极端情况、引号、多行命令等方面会很糟糕。前从终端执行 herodoc 会因您的eval 而失败。为什么不只是eval "$BASH_COMMAND"?如果用户执行set +o history.
  • 但是这些命令的问题在于,它们创建了一个新的子shell并执行它们,但我想在同一个shell中执行
  • in the same shell 所以也许重定向标准输出和标准错误?比如exec 1> >(tee stdout.txt)exec 2> >(tee stderr.txt)。喜欢exec 3>&2 2> >(tee stderr >&3)

标签: linux bash ubuntu terminal command-line-interface


【解决方案1】:

可以使用以下命令捕获 bash 脚本(例如 x.sh)的命令、标准错误和标准输出:

bash -x x.sh 2> >(tee err.txt) | tee out.txt

err.txt 将捕获已执行的命令(以“+”为前缀),以及每个命令的标准错误。 out.txt 将捕获输出

【讨论】:

  • 命令会以$PS4为前缀,默认为'+'
猜你喜欢
  • 1970-01-01
  • 2014-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 2017-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多