Unix Shell文件描述符

Vin*_*ick 1 unix bash ksh file-descriptor

我需要运行一个名为pg.sh的程序.它报告stdout输出日志.如何将stdout以及stderr和stdout保存到2个单独的日志文件中?

我搜索并得到以下代码

(pg.sh 2>&1 1>&3 ) 3>&1 1>&2 | tee output.log) > final.log 2>&1
Run Code Online (Sandbox Code Playgroud)

我理解1和2是指向stdout和stderr的文件描述符.3是另一个指向stdout的文件描述符.

上面的代码工作正常,但我不明白这是如何实现的.有人可以帮我写代码吗?

Nah*_*eul 5

从外部重定向开始:( .. ) 3>&1 1>&2,顺序很重要:

  • fd 3打开写为1的副本(stdout:这里是管道输入)
  • 然后fd 1被压碎为2(stderr)的副本(或重定向到stderr)

|输入是,则FD 3中,而标准错误不被捕获的三通,

嵌套重定向:

  • fd 2被重定向到stdout(被重定向到外部stderr)
  • fd 1被重定向到fd 3(被重定向到外部标准输出)

    因为tee重复记录的输出,(最后的重定向>final.log 2>&1,因为fd 2在fd 1之后打开,它们都被重定向到final.log)文件final.log将包含程序stdout和stderr,但output.log只有stdout.

也许它可以写得更容易,使用3>&1 1>&2 2>&3它可以反转stdout和stderr.

以下应该做同样的事情:

( pg.sh | tee output.log ) >final.log 2>&1
Run Code Online (Sandbox Code Playgroud)

下面将程序stdout写入output.log stderr到error.log,并写入final.log.

( ( pg.sh | tee output.log ) 3>&1 1>&2 2>&3 | tee error.log ) >final.log 2>&1
Run Code Online (Sandbox Code Playgroud)