我正在 Linux RedHat 中编写 SH Shell 脚本。我可以使用“set -x | tee > output.file”吗?

Dan*_*anL 1 bash shell set tee

在我的脚本的开头有“set -x”行。当然,这会将所有输出发送到屏幕。这正是我喜欢的,这样我就可以看到脚本正在做什么并解决问题。一旦脚本正常工作,我就会注释掉“set -x”行。

我想对 set -x 的输出进行发球,以便我有一个文件可以查看,而不是仅使用显示。有没有办法做到这一点?

我尝试过“set -x | tee ScriptNameHere.DEBUG”,它给了我一个名为 ScriptNameHere.DEBUG 的文件,其中包含零字节......一个空文件。

设置-x | tee scriptname.debug 设置 -x | tee -a 脚本名.debug

全部给我一个名为 scriptname.debug 的零字节文件。

Cha*_*ffy 5

您无法使用 sh 执行此操作,但可以使用 bash 执行此操作(只要您使用的不是 Apple 提供的旧版本)。

#!/usr/bin/env bash
case $BASH_VERSION in
  ''|[1-3].*|4.[012].*) echo "ERROR: bash 4.3 or newer required" >&2; exit 1;;
esac

exec {BASH_XTRACEFD}> >(tee -a ScriptNameHere.DEBUG >&2)
set -x
# ... other content of your script below
Run Code Online (Sandbox Code Playgroud)

解释一下上面的内容:

  • exec仅传递重定向而不是命令时,它会在当前 shell 中执行这些重定向。
  • 在 bash 4.x 及更高版本中,BASH_XTRACEFD给出 xtrace ( ) 将写入日志的文件描述符的编号set -x
  • 从 4.x 系列稍后的某个地方开始(4.1?4.3?),重定向{varname}>file动态地将文件描述符编号分配给"$varname"写入 file 的句柄的变量file
  • >(...)是一个进程替换,替换为文件名(通常在 Linux 上类似于/dev/fd/##/proc/self/fd/##),写入时会将内容传递给命令调用的程序...;一个用于阅读的是<(...).

因此,最终效果是tee在后台启动 的副本并将其附加到编号写入 的文件描述符$BASH_XTRACEFD,以便set -x稍后运行时,日志将写入到该副本tee,然后写入指定的文件。