You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本自定义日志函数失效求助:标准输出/错误重定向问题

Fixing Custom Logging for Shell Script Output/Error with Functions

Let's break down why your current redirection isn't working and walk through the correct way to route stdout and stderr to your custom logging functions.

Why Your Original Syntax Fails

Your command block uses invalid shell redirection syntax:

{ ls -la; cd /tmp/kjhdakdha; ls -la } 2 | errorLog 1 | OutputLog

Here's what's wrong:

  • 2 | errorLog doesn't make sense to the shell. The | operator connects the stdout of one command to the stdin of another, but 2 is just a file descriptor number—you can't pipe a file descriptor directly like this.
  • You're mixing up file descriptor redirection (using >/>&) with pipe syntax, which leads to the shell rejecting the command entirely.

Correct Solution: Use Process Substitution

To route stdout and stderr to separate custom functions, we'll use bash process substitution (>(command)), which creates a pseudo-file that feeds output to your function's stdin. This lets us handle each stream independently.

Step 1: Ensure Your Logging Functions Work with Stdin

First, make sure your OutputLog and errorLog functions read input from stdin (this is the standard way to handle piped input):

# Define log file paths
OutputLogFile="/path/to/your/info.log"
ErrorLogFile="/path/to/your/error.log"

# Info logging function: reads lines from stdin, formats, and writes to log file
OutputLog() {
    while IFS= read -r line; do
        # Add timestamp and log level
        echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] $line" >> "$OutputLogFile"
    done
}

# Error logging function: same pattern for stderr
errorLog() {
    while IFS= read -r line; do
        echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] $line" >> "$ErrorLogFile"
    done
}
  • IFS= read -r line preserves leading/trailing spaces and backslashes in the input lines, which avoids mangling output like ls -la listings.

Step 2: Redirect Streams to Your Functions

Use process substitution to route stdout (fd 1) to OutputLog and stderr (fd 2) to errorLog:

{ ls -la; cd /tmp/kjhdakdha; ls -la; } 1> >(OutputLog) 2> >(errorLog)

Let's break this down:

  • 1> >(OutputLog): Redirect stdout (file descriptor 1) to the pseudo-file created by >(OutputLog), which feeds all stdout lines into the OutputLog function's stdin.
  • 2> >(errorLog): Redirect stderr (file descriptor 2) to errorLog the same way.
  • The curly braces { ... } group your commands so their combined output/stderr is redirected.

Key Notes to Avoid Issues

  • Use bash, not sh: Process substitution is a bash-specific feature. Make sure your script starts with #!/bin/bash (not #!/bin/sh) to enable this.
  • Check file permissions: Ensure the user running the script has write access to OutputLogFile and ErrorLogFile.
  • Test edge cases: If your commands produce partial lines (e.g., progress bars), you might need to tweak the function to handle unbuffered input, but for standard line-based output like ls or error messages, the above works perfectly.

Example Test Run

After setting up the functions and variables, run the command block. You'll see:

  • The output of ls -la in OutputLogFile with timestamps and [INFO] tags.
  • The error message from cd /tmp/kjhdakdha (since that directory doesn't exist) in ErrorLogFile with [ERROR] tags.

内容的提问来源于stack exchange,提问作者Suganya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:56:00