英文:
I am writing a SH Shell script in Linux RedHat. Can I use "set -x | tee > output.file"?
问题
在我的脚本开头,我有一行 "set -x"。这当然会将所有输出发送到屏幕上。这正是我喜欢的,这样我可以看到脚本正在做什么并解决问题。一旦脚本正确工作,我会注释掉 "set -x" 这一行。
我想将 "set -x" 的输出保存到一个文件中,而不是仅在屏幕上显示。有没有办法做到这一点?
我尝试过 "set -x | tee ScriptNameHere.DEBUG",但它给我生成了一个名为 ScriptNameHere.DEBUG 的零字节文件...一个空文件。
"set -x | tee scriptname.debug"
"set -x | tee -a scriptname.debug"
都会生成一个名为 scriptname.debug 的零字节文件。
英文:
At the beginning of my script I have the "set -x" line. This, of course, sends all output to the screen. This is exactly what I like so that I can see what the script is doing and fix issues along the way. Once the script works correctly I comment out the "set -x" line.
I would like to tee the output of set -x so that I have a file to look at instead of using the display only. Is there a way to do this?
I've tried "set -x | tee ScriptNameHere.DEBUG" and it gives me a file named ScriptNameHere.DEBUG with ZERO bytes in it... an empty file.
set -x | tee scriptname.debug
set -x | tee -a scriptname.debug
All give me a Zero byte file named scriptname.debug.
答案1
得分: 5
你不能使用sh来实现这个,但你可以使用bash(只要你不在苹果提供的古老版本上)。
#!/usr/bin/env bash
case $BASH_VERSION in
''|[1-3].*|4.[012].*) echo "错误:需要bash 4.3或更新版本" >&2; exit 1;;
esac
exec {BASH_XTRACEFD}> >(tee -a ScriptNameHere.DEBUG >&2)
set -x
# ... 你的脚本其他内容在下面
解释上述内容:
- 当
exec
只传递重定向,而不是命令时,它在当前shell中执行这些重定向。 - 在bash 4.x及更高版本中,
BASH_XTRACEFD
给出了xtrace (set -x
)将写入日志的文件描述符号。 - 从4.x系列的某个版本开始(4.1?4.3?),
{varname}>file
的重定向动态地为变量"$varname"
分配一个写入文件file
的文件描述符号。 >(...)
是一个进程替代,被替换为一个文件名(通常在Linux上类似于/dev/fd/##
或/proc/self/fd/##
),当写入时,它将向由命令...
调用的程序传递内容;一个用于读取的变种是<(...)
因此,净效果是在后台启动一个tee
的副本并将其附加到一个文件描述符号,该文件描述符号的编号写入了$BASH_XTRACEFD
,因此当稍后运行set -x
时,日志将被写入该tee
的副本,然后写入指定的文件。
英文:
You can't do this with sh, but you can do it with bash (as long as you aren't on the ancient version shipped by 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
Explaining the above:
- When
exec
is passed only redirections, and not a command, it performs those redirections in the current shell. - In bash 4.x and later,
BASH_XTRACEFD
gives the number of the file descriptor where xtrace (set -x
) will write logs. - Starting somewhere later in the 4.x series (4.1? 4.3?), a redirection of
{varname}>file
dynamically assigns a file descriptor number to the variable"$varname"
of a handle writing to filefile
. >(...)
is a process substitution, replaced with a filename (typically on Linux something like/dev/fd/##
or/proc/self/fd/##
) that, when written to, will deliver content to the program invoked by the command...
; one for read is instead<(...)
.
Thus, the net effect is to start a copy of tee
in the background and attach it to a file descriptor whose number is written to $BASH_XTRACEFD
, such that when set -x
is later run, the logs will be written to that copy of tee
and thereafter to the specified file.
答案2
得分: 1
set -x | whatever
或 >wherever
只会发送set -x
本身的输出 - set -x
并不输出任何东西!它是用来 开启 跟踪输出的,这些输出来自于shell,而不是shell运行的任何命令。
你可以通过重定向标准错误来捕获它,例如:
exec 2>>trace.out
set -x
或者,如果要将它同时发送到屏幕和文件,可以使用以下命令:
exec 2> >(tee -a trace.out)
set -x
英文:
set -x | whatever
or >wherever
just sends the output of the set -x
itself - which doesn't output anything! It turns on tracing output, which comes from the shell, not any of the commands the shell runs.
You can capture it, though; just by redirecting stderr, e.g. with
exec 2>>trace.out
set -x
or, to have it go to both the screen and the file
exec 2> >(tee -a trace.out)
set -x
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论