在BSD风格的UNIX上使用ksh。如何将stderr重定向到tee和文件

时间:2016-02-21 00:32:57

标签: shell unix redirect stdout stderr

提出的类似问题here

但它对我不起作用

id

此命令不会重定向stderr stdop

id

我在AIX上运行一些类似于没有GNU扩展的BSD的UNIX 这是ksh

"shell.ksh"  > >(tee here.log ) 2> >(tee err.log)
ksh: 0403-057 Syntax error: `>' is not expected.

任何短暂而甜蜜的解决方案?

1 个答案:

答案 0 :(得分:1)

这是一个应该做你想要的包装脚本。我无法确认它是否适用于AIX ksh,但它可以使用sh (AT&T Research) 93u+ 2012-08-01(Debian的ksh包将其称为“Korn shell的Real,AT& T版本。”这是故意的{ {3}}也不是pdksh分叉。)

这是可移植的,应该适用于所有POSIX shell。

PIPE1 + 2.ksh

#!/bin/ksh

touch err.log here.log      # create the logs now so tail -f doesn't complain
tail -f here.log &          # follow the output we'll pipe to later (run in bg)
HERE=$!                     # save the process ID of this backgrounded process
tail -f err.log >&2 &       # follow output (as above), pipe output to stderr
ERR=$!                      # save the process ID

"$@" > here.log 2> err.log  # run given command and pipe stdout and stderr
RET=$?                      # save return value

sleep 1                     # tail polls at 1/s, so wait one second

kill $HERE $ERR             # stop following those logs

exit $RET                   # restore the exit code from given command

因此,您将其作为pipe1+2.ksh shell.ksh调用(假设两个命令都在您的路径中)。

这是shell.ksh的测试版本:

#!/bin/ksh

echo this output is stdout 1
echo this output is stderr >&2
echo this output is stdout 2

和试运行:

# ksh pipe1+2.ksh ksh shell.ksh
this output is stdout 1
this output is stdout 2
this output is stderr
# cat here.log
this output is stdout 1
this output is stdout 2
# cat err.log
this output is stderr

注意:由于tail -f不是即时的,因此stdout vs stderr会稍微失灵。它在运行之间甚至不一致,至少对于运行速度与echo一样快的代码。

我怀疑你的tail版本支持它,但是GNU tail有一个-s SECONDS标志,可以让你指定一个不同的轮询间隔作为十进制值,所以你可以尝试例如tail -f -s 0.01 …改进显示内容的顺序。如果您的sleep版本也支持小数值,请将其更改为与该数字匹配。

(我最初根据惊人的mksh中的一个“更复杂的组合”制作了一个复杂的文件描述符管道响应,但这似乎不起作用。请参阅注释和/或Csh Programming Considered Harmful。)