我想在一个ksh脚本(使用exec)中创建一个管道,将管道连接到一个T形管,并将输出发送到管道.
当前:
#Redirect EVERYTHING exec 3>&1 #Save STDOUT as 3 exec 4>&2 #Save STDERR as 4 exec 1>${Log} #Redirect STDOUT to a log exec 2>&1 #Redirect STDERR to STDOUT
我想做什么(但我没有正确的语法):
#Redirect EVERYTHING exec 3>&1 #Save STDOUT as 3 exec 4>&2 #Save STDERR as 4 exec 1>tee -a ${Log} >&3 #Redirect STDOUT to a log exec 2>&1 #Redirect STDERR to STDOUT
我怎样才能创建这个管道?
这是我使用的解决方案.它在我的Mac上的ksh下工作.它很好地封装在start_logging()和stop_logging()函数中,使生活变得轻松.
代码在实践中看起来像这样:
# Optional: # Set the name and location of the log file. # OUTPUT_LOG=output.log # default # Set the name and location of the named pipe used. # OUTPUT_PIPE=output.pipe # default start_logging # Default is to append to an existing log file. # start_logging delete_existing_logfile echo "This is on standard out" echo "This is on standard err" >&2 stop_logging
这是整个文件.启动和停止功能以及上面的示例都位于文件的底部.为了更容易使用,只需将启动和停止功能放在他们自己的文件中,然后在需要记录的脚本中将它们提取出来.
#!/bin/sh # Author: Harvey Chapman <hchapman _AT_ 3gfp.com> # Description: POSIX shell functions that can be used with tee to simultaneously put # stderr and stdout to both a file and stdout # # Based on: # Re: How to redirect stderr and stdout to a file plus display at the same time # http://www.travishartwell.net/blog/2006/08/19_2220 # # Original example function from Travis Hartwell's blog. # Note: I've made minor changes to it. example() { OUTPUT_LOG=output.log OUTPUT_PIPE=output.pipe # This should really be -p to test that it's a pipe. if [ ! -e $OUTPUT_PIPE ]; then mkfifo $OUTPUT_PIPE fi # This should really be -f to test that it's a regular file. if [ -e $OUTPUT_LOG ]; then rm $OUTPUT_LOG fi exec 3>&1 4>&2 tee $OUTPUT_LOG < $OUTPUT_PIPE >&3 & tpid=$! exec > $OUTPUT_PIPE 2>&1 echo "This is on standard out" echo "This is on standard err" >&2 exec 1>&3 3>&- 2>&4 4>&- wait $tpid rm $OUTPUT_PIPE } # A slightly reduced version of example() example2() { OUTPUT_LOG=output.log OUTPUT_PIPE=output.pipe rm -f $OUTPUT_PIPE mkfifo $OUTPUT_PIPE rm -f $OUTPUT_LOG tee $OUTPUT_LOG < $OUTPUT_PIPE & tpid=$! exec 3>&1 4>&2 >$OUTPUT_PIPE 2>&1 echo "This is on standard out" echo "This is on standard err" >&2 exec 1>&3 3>&- 2>&4 4>&- wait $tpid rm -f $OUTPUT_PIPE } # # Logging methods based on above. See the example below for how to use them. # # Usage: start_logging [delete_existing_logfile] start_logging() { # Check to see if OUTPUT_LOG and OUTPUT_PIPE need to be defined. if [ -z "$OUTPUT_LOG" ]; then OUTPUT_LOG=output.log fi if [ -z "$OUTPUT_PIPE" ]; then OUTPUT_PIPE=output.pipe fi # Make sure that we're not already logging. if [ -n "$OUTPUT_PID" ]; then echo "Logging already started!" return 1 fi # Always remove the log and pipe first. rm -f $OUTPUT_PIPE # Delete the logfile first if told to. if [ "$1" = delete_existing_logfile ]; then rm -f $OUTPUT_LOG fi mkfifo $OUTPUT_PIPE tee -a $OUTPUT_LOG < $OUTPUT_PIPE & OUTPUT_PID=$! exec 3>&1 4>&2 >$OUTPUT_PIPE 2>&1 } stop_logging() { # Make sure that we're currently logging. if [ -z "$OUTPUT_PID" ]; then echo "Logging not yet started!" return 1 fi exec 1>&3 3>&- 2>&4 4>&- wait $OUTPUT_PID rm -f $OUTPUT_PIPE unset OUTPUT_PID } example3() { start_logging #start_logging delete_existing_logfile echo "This is on standard out" echo "This is on standard err" >&2 stop_logging } #example #example2 example3