如何在使用“tee”时将标准错误写入文件 用管子?

发布于 2024-07-15 17:52:11 字数 457 浏览 13 评论 0原文

我知道如何使用 tee 编写输出(标准将 aaa.sh 的输出)发送到 bbb.out,同时仍将其显示在终端中:

./aaa.sh | tee bbb.out

我现在还应该如何编写 标准错误到名为ccc.out的文件,同时仍然显示它?

I know how to use tee to write the output (standard output) of aaa.sh to bbb.out, while still displaying it in the terminal:

./aaa.sh | tee bbb.out

How would I now also write standard error to a file named ccc.out, while still having it displayed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

半枫 2024-07-22 17:52:11

我假设您仍然希望在终端上看到标准错误和标准输出。 你可以去 Josh Kelley 的回答,但我发现在后台保留一个 tail ,它输出的日志文件非常黑客和笨拙。 请注意,您需要如何保留额外的 文件描述符 并在之后通过杀死它来进行清理,从技术上讲应该是在 trap '...' EXIT 中执行此操作。

有一个更好的方法可以做到这一点,并且您已经发现了它:tee

只是,不要仅将其用于标准输出,而是要有一个用于标准输出的 T 恤和一个用于标准错误的 T 恤。 您将如何实现这一目标? 进程替换和文件重定向:

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

让我们将其分开并解释:

> >(..)

>(...)(进程替换)创建一个 FIFO 并让 tee 监听它。 然后,它使用 >(文件重定向)将 command 的标准输出重定向到您的第一个 tee 正在侦听的 FIFO。

第二个也是同样的事情:

2> >(tee -a stderr.log >&2)

我们再次使用进程替换来创建一个从标准输入读取并将其转储到 stderr.log 的 tee 进程。 tee 将其输入输出回标准输出,但由于其输入是我们的标准错误,因此我们希望再次将 tee 的标准输出重定向到我们的标准错误。 然后我们使用文件重定向将command的标准错误重定向到FIFO的输入(tee的标准输入)。

请参阅输入和输出

流程替换是您真正喜欢的事情之一选择 Bash 作为 shell 而不是 sh(POSIX 或 Bourne)是一个好处。


sh 中,您必须手动执行操作:

out="${TMPDIR:-/tmp}/out.$" err="${TMPDIR:-/tmp}/err.$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"

I'm assuming you want to still see standard error and standard output on the terminal. You could go for Josh Kelley's answer, but I find keeping a tail around in the background which outputs your log file very hackish and cludgy. Notice how you need to keep an extra file descriptor and do cleanup afterward by killing it and technically should be doing that in a trap '...' EXIT.

There is a better way to do this, and you've already discovered it: tee.

Only, instead of just using it for your standard output, have a tee for standard output and one for standard error. How will you accomplish this? Process substitution and file redirection:

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

Let's split it up and explain:

> >(..)

>(...) (process substitution) creates a FIFO and lets tee listen on it. Then, it uses > (file redirection) to redirect the standard output of command to the FIFO that your first tee is listening on.

The same thing for the second:

2> >(tee -a stderr.log >&2)

We use process substitution again to make a tee process that reads from standard input and dumps it into stderr.log. tee outputs its input back on standard output, but since its input is our standard error, we want to redirect tee's standard output to our standard error again. Then we use file redirection to redirect command's standard error to the FIFO's input (tee's standard input).

See Input And Output

Process substitution is one of those really lovely things you get as a bonus of choosing Bash as your shell as opposed to sh (POSIX or Bourne).


In sh, you'd have to do things manually:

out="${TMPDIR:-/tmp}/out.$" err="${TMPDIR:-/tmp}/err.$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"
绅士风度i 2024-07-22 17:52:11

简单地说:

./aaa.sh 2>&1 | tee -a log

这只是将标准错误重定向到标准输出,因此 tee 会回显到日志和屏幕。 也许我错过了一些东西,因为其他一些解决方案看起来非常复杂。

注意:从 Bash 版本 4 开始,您可以使用 |& 作为 2>&1 | 的缩写:

./aaa.sh |& tee -a log

Simply:

./aaa.sh 2>&1 | tee -a log

This simply redirects standard error to standard output, so tee echoes both to log and to the screen. Maybe I'm missing something, because some of the other solutions seem really complicated.

Note: Since Bash version 4 you may use |& as an abbreviation for 2>&1 |:

./aaa.sh |& tee -a log
莫多说 2024-07-22 17:52:11

这对于通过 Google 找到此内容的人可能很有用。 只需取消注释您想要尝试的示例即可。 当然,您可以随意重命名输出文件。

#!/bin/bash

STATUSFILE=x.out
LOGFILE=x.log

### All output to screen
### Do nothing, this is the default


### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1


### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1


### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)


### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)


### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}


### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)


### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}


### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)


echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}

This may be useful for people finding this via Google. Simply uncomment the example you want to try out. Of course, feel free to rename the output files.

#!/bin/bash

STATUSFILE=x.out
LOGFILE=x.log

### All output to screen
### Do nothing, this is the default


### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1


### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1


### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)


### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)


### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}


### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)


### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}


### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)


echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}
堇色安年 2024-07-22 17:52:11

换句话说,您希望将 stdout 通过管道传输到一个过滤器 (tee bbb.out),并将 stderr 通过管道传输到另一个过滤器 (tee ccc.out)。 没有标准方法可以将 stdout 以外的任何内容通过管道传输到另一个命令中,但您可以通过调整文件描述符来解决这个问题。

{ { ./aaa.sh | tee bbb.out; } 2>&1 1>&3 | tee ccc.out; } 3>&1 1>&2

另请参阅如何 grep 标准错误流 (stderr)?什么时候会使用额外的文件描述符?

在 bash(以及 ksh 和 zsh)中,但不能在其他 POSIX shell(例如 dash)中,您可以使用 进程替换

./aaa.sh > >(tee bbb.out) 2> >(tee ccc.out)

请注意,在 bash 中,此命令一旦 ./aaa.sh 完成,即使 tee 命令仍在执行(ksh 和 zsh 确实等待子进程)。 如果您执行类似 ./aaa.sh > 的操作,这可能会出现问题 >(tee bbb.out) 2> >(tee ccc.out); process_logs bbb.out ccc.out。 在这种情况下,请改用文件描述符杂耍或 ksh/zsh。

In other words, you want to pipe stdout into one filter (tee bbb.out) and stderr into another filter (tee ccc.out). There is no standard way to pipe anything other than stdout into another command, but you can work around that by juggling file descriptors.

{ { ./aaa.sh | tee bbb.out; } 2>&1 1>&3 | tee ccc.out; } 3>&1 1>&2

See also How to grep standard error stream (stderr)? and When would you use an additional file descriptor?

In bash (and ksh and zsh), but not in other POSIX shells such as dash, you can use process substitution:

./aaa.sh > >(tee bbb.out) 2> >(tee ccc.out)

Beware that in bash, this command returns as soon as ./aaa.sh finishes, even if the tee commands are still executed (ksh and zsh do wait for the subprocesses). This may be a problem if you do something like ./aaa.sh > >(tee bbb.out) 2> >(tee ccc.out); process_logs bbb.out ccc.out. In that case, use file descriptor juggling or ksh/zsh instead.

段念尘 2024-07-22 17:52:11

要将标准错误重定向到文件,将标准输出显示到屏幕,并将标准输出保存到文件:

./aaa.sh 2>ccc.out | tee ./bbb.out

要将标准错误和标准输出都显示到屏幕并将两者保存到文件,可以使用 Bash 的 I/O 重定向

#!/bin/bash

# Create a new file descriptor 4, pointed at the file
# which will receive standard error.
exec 4<>ccc.out

# Also print the contents of this file to screen.
tail -f ccc.out &

# Run the command; tee standard output as normal, and send standard error
# to our file descriptor 4.
./aaa.sh 2>&4 | tee bbb.out

# Clean up: Close file descriptor 4 and kill tail -f.
exec 4>&-
kill %1

To redirect standard error to a file, display standard output to the screen, and also save standard output to a file:

./aaa.sh 2>ccc.out | tee ./bbb.out

To display both standard error and standard output to screen and also save both to a file, you can use Bash's I/O redirection:

#!/bin/bash

# Create a new file descriptor 4, pointed at the file
# which will receive standard error.
exec 4<>ccc.out

# Also print the contents of this file to screen.
tail -f ccc.out &

# Run the command; tee standard output as normal, and send standard error
# to our file descriptor 4.
./aaa.sh 2>&4 | tee bbb.out

# Clean up: Close file descriptor 4 and kill tail -f.
exec 4>&-
kill %1
秋日私语 2024-07-22 17:52:11

如果使用 Bash:

# Redirect standard out and standard error separately
% cmd >stdout-redirect 2>stderr-redirect

# Redirect standard error and out together
% cmd >stdout-redirect 2>&1

# Merge standard error with standard out and pipe
% cmd 2>&1 |cmd2

信用(不是从我的头脑中回答)在这里:回复:bash:stderr & 更多(标准错误的管道)

If using Bash:

# Redirect standard out and standard error separately
% cmd >stdout-redirect 2>stderr-redirect

# Redirect standard error and out together
% cmd >stdout-redirect 2>&1

# Merge standard error with standard out and pipe
% cmd 2>&1 |cmd2

Credit (not answering from the top of my head) goes here: Re: bash : stderr & more (pipe for stderr)

生生漫 2024-07-22 17:52:11

如果您使用的是 Z shell (zsh),则可以使用多个重定向,因此您甚至不需要 tee

./cmd 1>&1 2>&2 1>out_file 2>err_file

在这里,您只需将每个流重定向到其本身和目标文件。


完整示例

% (echo "out"; echo "err">/dev/stderr) 1>&1 2>&2 1>/tmp/out_file 2>/tmp/err_file
out
err
% cat /tmp/out_file
out
% cat /tmp/err_file
err

请注意,这需要设置 MULTIOS 选项(这是默认值)。

MULTIOS

尝试多次重定向时执行隐式 teecat(请参阅 重定向)。

If you're using Z shell (zsh), you can use multiple redirections, so you don't even need tee:

./cmd 1>&1 2>&2 1>out_file 2>err_file

Here you're simply redirecting each stream to itself and the target file.


Full example

% (echo "out"; echo "err">/dev/stderr) 1>&1 2>&2 1>/tmp/out_file 2>/tmp/err_file
out
err
% cat /tmp/out_file
out
% cat /tmp/err_file
err

Note that this requires the MULTIOS option to be set (which is the default).

MULTIOS

Perform implicit tees or cats when multiple redirections are attempted (see Redirection).

生死何惧 2024-07-22 17:52:11

就像lhunath很好解释的接受答案一样,您可以使用

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

小心,如果您使用bash,您可能会遇到一些问题

让我以 matthew-wilcoxson 为例。

对于那些“眼见为实”的人,快速测试一下:

(echo "Test Out";>&2 echo "Test Err") >   >(tee stdout.log) 2>   >(tee stderr.log >&2) 
  

我个人而言,当我尝试时,我得到了这样的结果:

user@computer:~$ (echo "Test Out";>&2 echo "Test Err") > >(tee stdout.log) 2> >(tee stderr.log >&2)
user@computer:~$ Test Out
Test Err

两条消息不会出现在同一级别。 为什么 Test Out 看起来像是我以前的命令?

提示位于空白行,让我认为该过程尚未完成,当我按 Enter 时,此修复它。
当我检查文件内容时,一切正常,并且重定向有效。

让我们再进行一次测试。

function outerr() {
  echo "out"     # stdout
  echo >&2 "err" # stderr
}
user@computer:~$ outerr
out
err

user@computer:~$ outerr >/dev/null
err

user@computer:~$ outerr 2>/dev/null
out

再次尝试重定向,但使用此功能:

function test_redirect() {
  fout="stdout.log"
  ferr="stderr.log"
  echo "$ outerr"
  (outerr) > >(tee "$fout") 2> >(tee "$ferr" >&2)
  echo "# $fout content: "
  cat "$fout"
  echo "# $ferr content: "
  cat "$ferr"
}

就我个人而言,我有这样的结果:

user@computer:~$ test_redirect
$ outerr
# stdout.log content:
out
out
err
# stderr.log content:
err
user@computer:~$

空行上没有提示,但我看不到正常输出。 stdout.log内容似乎是错误的,只有stderr.log似乎没问题。

如果我重新启动它,输出可能会有所不同......

那么,为什么呢?

因为,就像这里解释的

请注意,在 bash 中,此命令会在 [第一个命令] 完成后立即返回,即使 tee 命令仍在执行(ksh 和 zsh 会等待子进程)

因此,如果您使用 Bash,最好使用 < 中给出的更好示例a href="https://stackoverflow.com/a/14737103/6862843">这个其他答案:

{ { outerr | tee "$fout"; } 2>&1 1>&3 | tee "$ferr"; } 3>&1 1>&2

它将解决以前的问题。

现在的问题是,如何检索退出状态代码?

$? 不起作用。

我没有找到比使用 set -o pipelinefail 打开 pipelinefail (set +o pipelinefail 关闭)并使用 ${PIPESTATUS[0]} 更好的解决方案像这样:

function outerr() {
  echo "out"
  echo >&2 "err"
  return 11
}

function test_outerr() {
  local - # To preserve set option
  ! [[ -o pipefail ]] && set -o pipefail; # Or use second part directly
  local fout="stdout.log"
  local ferr="stderr.log"
  echo "$ outerr"
  { { outerr | tee "$fout"; } 2>&1 1>&3 | tee "$ferr"; } 3>&1 1>&2
  # First save the status or it will be lost
  local status="${PIPESTATUS[0]}" # Save first, the second is 0, perhaps tee status code.
  echo "==="
  echo "# $fout content :"
  echo "<==="
  cat "$fout"
  echo "===>"
  echo "# $ferr content :"
  echo "<==="
  cat "$ferr"
  echo "===>"
  if (( status > 0 )); then
    echo "Fail $status > 0"
    return "$status" # or whatever
  fi
}
user@computer:~$ test_outerr
$ outerr
err
out
===
# stdout.log content:
<===
out
===>
# stderr.log content:
<===
err
===>
Fail 11 > 0

Like the accepted answer well explained by lhunath, you can use

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

Beware than if you use bash you could have some issue.

Let me take the matthew-wilcoxson example.

And for those who "seeing is believing", a quick test:

(echo "Test Out";>&2 echo "Test Err") > >(tee stdout.log) 2> >(tee stderr.log >&2)

Personally, when I try, I have this result:

user@computer:~$ (echo "Test Out";>&2 echo "Test Err") > >(tee stdout.log) 2> >(tee stderr.log >&2)
user@computer:~$ Test Out
Test Err

Both messages do not appear at the same level. Why does Test Out seem to be put like if it is my previous command?

The prompt is on a blank line letting me think the process is not finished, and when I press Enter this fix it.
When I check the content of the files, it is ok, and redirection works.

Let’s take another test.

function outerr() {
  echo "out"     # stdout
  echo >&2 "err" # stderr
}
user@computer:~$ outerr
out
err

user@computer:~$ outerr >/dev/null
err

user@computer:~$ outerr 2>/dev/null
out

Trying again the redirection, but with this function:

function test_redirect() {
  fout="stdout.log"
  ferr="stderr.log"
  echo "$ outerr"
  (outerr) > >(tee "$fout") 2> >(tee "$ferr" >&2)
  echo "# $fout content: "
  cat "$fout"
  echo "# $ferr content: "
  cat "$ferr"
}

Personally, I have this result:

user@computer:~$ test_redirect
$ outerr
# stdout.log content:
out
out
err
# stderr.log content:
err
user@computer:~$

No prompt on a blank line, but I don't see normal output. The stdout.log content seem to be wrong, and only stderr.log seem to be ok.

If I relaunch it, the output can be different...

So, why?

Because, like explained here:

Beware that in bash, this command returns as soon as [first command] finishes, even if the tee commands are still executed (ksh and zsh do wait for the subprocesses)

So, if you use Bash, prefer use the better example given in this other answer:

{ { outerr | tee "$fout"; } 2>&1 1>&3 | tee "$ferr"; } 3>&1 1>&2

It will fix the previous issues.

Now, the question is, how to retrieve exit status code?

$? does not work.

I have no found better solution than switch on pipefail with set -o pipefail (set +o pipefail to switch off) and use ${PIPESTATUS[0]} like this:

function outerr() {
  echo "out"
  echo >&2 "err"
  return 11
}

function test_outerr() {
  local - # To preserve set option
  ! [[ -o pipefail ]] && set -o pipefail; # Or use second part directly
  local fout="stdout.log"
  local ferr="stderr.log"
  echo "$ outerr"
  { { outerr | tee "$fout"; } 2>&1 1>&3 | tee "$ferr"; } 3>&1 1>&2
  # First save the status or it will be lost
  local status="${PIPESTATUS[0]}" # Save first, the second is 0, perhaps tee status code.
  echo "==="
  echo "# $fout content :"
  echo "<==="
  cat "$fout"
  echo "===>"
  echo "# $ferr content :"
  echo "<==="
  cat "$ferr"
  echo "===>"
  if (( status > 0 )); then
    echo "Fail $status > 0"
    return "$status" # or whatever
  fi
}
user@computer:~$ test_outerr
$ outerr
err
out
===
# stdout.log content:
<===
out
===>
# stderr.log content:
<===
err
===>
Fail 11 > 0
倒带 2024-07-22 17:52:11

以下内容适用于进程替换不可用的 KornShell (ksh),

# create a combined (standard input and standard output) collector
exec 3 <> combined.log

# stream standard error instead of standard output to tee, while draining all standard output to the collector
./aaa.sh 2>&1 1>&3 | tee -a stderr.log 1>&3

# cleanup collector
exec 3>&-

这里真正的技巧是 2>&1 1>&3 的序列,在我们的例子中,它重定向了标准错误到标准输出,并将标准输出重定向到 文件描述符 3. 此时标准错误和标准输出尚未合并。

实际上,标准错误(作为标准输入)被传递到 tee,并在其中记录到 stderr.log 并重定向到文件描述符 3。

文件描述符 3 正在记录始终将其保存到 combined.log 中。 因此,combined.log 包含标准输出和标准错误。

The following will work for KornShell (ksh) where the process substitution is not available,

# create a combined (standard input and standard output) collector
exec 3 <> combined.log

# stream standard error instead of standard output to tee, while draining all standard output to the collector
./aaa.sh 2>&1 1>&3 | tee -a stderr.log 1>&3

# cleanup collector
exec 3>&-

The real trick here, is the sequence of the 2>&1 1>&3 which in our case redirects the standard error to standard output and redirects the standard output to file descriptor 3. At this point the standard error and standard output are not combined yet.

In effect, the standard error (as standard input) is passed to tee where it logs to stderr.log and also redirects to file descriptor 3.

And file descriptor 3 is logging it to combined.log all the time. So the combined.log contains both standard output and standard error.

陌上青苔 2024-07-22 17:52:11

就我而言,脚本正在运行命令,同时将 stdout 和 stderr 重定向到文件,例如:

cmd > log 2>&1

我需要更新它,以便在出现故障时,根据错误消息采取一些操作。 我当然可以删除 dup 2>&1 并从脚本中捕获 stderr,但错误消息不会进入日志文件以供参考。 虽然接受的 来自 lhunath 的回答 应该做同样的事情,它将 stdoutstderr 重定向到不同的文件,这不是我想要的,但是它帮助我找到了我需要的确切解决方案:

(cmd 2> >(tee /dev/stderr)) > log

通过上述内容,日志将拥有 stdoutstderr 的副本,并且我可以捕获 stderr 来自我的脚本,而不必担心 stdout

In my case, a script was running command while redirecting both stdout and stderr to a file, something like:

cmd > log 2>&1

I needed to update it such that when there is a failure, take some actions based on the error messages. I could of course remove the dup 2>&1 and capture the stderr from the script, but then the error messages won't go into the log file for reference. While the accepted answer from lhunath is supposed to do the same, it redirects stdout and stderr to different files, which is not what I want, but it helped me to come up with the exact solution that I need:

(cmd 2> >(tee /dev/stderr)) > log

With the above, log will have a copy of both stdout and stderr and I can capture stderr from my script without having to worry about stdout.

耶耶耶 2024-07-22 17:52:11

谢谢 lhunath 获取 POSIX 中的答案

这是我在 POSIX 中需要的更复杂的情况并进行了正确的修复:

# Start script main() function
# - We redirect standard output to file_out AND terminal
# - We redirect standard error to file_err, file_out AND terminal
# - Terminal and file_out have both standard output and standard error, while file_err only holds standard error

main() {
    # my main function
}

log_path="/my_temp_dir"
pfout_fifo="${log_path:-/tmp}/pfout_fifo.$"
pferr_fifo="${log_path:-/tmp}/pferr_fifo.$"

mkfifo "$pfout_fifo" "$pferr_fifo"
trap 'rm "$pfout_fifo" "$pferr_fifo"' EXIT

tee -a "file_out" < "$pfout_fifo" &
    tee -a "file_err" < "$pferr_fifo" >>"$pfout_fifo" &
    main "$@" >"$pfout_fifo" 2>"$pferr_fifo"; exit

Thanks lhunath for the answer in POSIX.

Here's a more complex situation I needed in POSIX with the proper fix:

# Start script main() function
# - We redirect standard output to file_out AND terminal
# - We redirect standard error to file_err, file_out AND terminal
# - Terminal and file_out have both standard output and standard error, while file_err only holds standard error

main() {
    # my main function
}

log_path="/my_temp_dir"
pfout_fifo="${log_path:-/tmp}/pfout_fifo.$"
pferr_fifo="${log_path:-/tmp}/pferr_fifo.$"

mkfifo "$pfout_fifo" "$pferr_fifo"
trap 'rm "$pfout_fifo" "$pferr_fifo"' EXIT

tee -a "file_out" < "$pfout_fifo" &
    tee -a "file_err" < "$pferr_fifo" >>"$pfout_fifo" &
    main "$@" >"$pfout_fifo" 2>"$pferr_fifo"; exit
往事随风而去 2024-07-22 17:52:11

发送到标准错误 (STDERR) 的编译错误可以通过以下方式重定向或保存到文件中:

Bash:

gcc temp.c &> error.log

C shell (csh):

% gcc temp.c |& tee error.log

参见:如何将编译/构建错误重定向到文件?

Compilation errors which are sent to standard error (STDERR) can be redirected or save to a file by:

Bash:

gcc temp.c &> error.log

C shell (csh):

% gcc temp.c |& tee error.log

See: How can I redirect compilation/build error to a file?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文