Linux脚本exec重定向问题:如何同时输出到文件与控制台?
Hey, I totally get what you're stuck on here—you want your script's output (both regular messages and errors) to go to a log file and show up in the terminal, but the exec + tee commands you tried only seem to do one or the other. Let's fix this with the right syntax and explain why your previous attempts didn't work.
正确的exec+tee实现方式
The correct command to set up global redirection for both stdout and stderr to both terminal and log file is:
exec > >(tee -a "$LOGFILE") 2>&1
Let's break down why this works and what you might have missed before:
- The space between
>and>(tee ...)is critical—this is process substitution syntax, which tells bash to create a temporary pipe to theteecommand. If you skip the space, the shell misinterprets the command. - Wrapping
"$LOGFILE"in double quotes prevents issues if your log file path has spaces or special characters (always a good habit!). 2>&1redirects stderr to stdout, so error messages get caught byteetoo—they'll show up in the terminal and get appended to the log file.
为什么你之前的尝试失败了
Let's go through why those commands didn't work:
exec &> >(tee -a $LOGFILE) 2>&1: The&>already redirects both stdout and stderr to the process substitution. Adding2>&1afterward is redundant and can cause the shell to mishandle the file descriptors, leading to only one output stream working.exec >> $LOGFILE 2>&1 && tail -f $LOGFILE: Theexeccommand replaces the current shell process—once it runs, thetail -fpart never executes. That's why you only get output in the log file, not the terminal.
兼容POSIX shell的替代方案
If you're working with a strict POSIX shell (not bash, which supports process substitution by default), the script command is a reliable alternative:
script -a -q "$LOGFILE"
-atellsscriptto append to the log file instead of overwriting it.-qenables quiet mode, so you don't get extra "Script started/ended" messages cluttering your output.
After running this, all subsequent commands in the script will output to both the terminal and the log file. To exit thescriptsession (and stop logging), just runexit.
逐命令处理的备选方案
If you don't want to set up global redirection, you can pipe individual commands to tee:
# 仅重定向标准输出 echo "Regular output" | tee -a "$LOGFILE" # 同时重定向标准输出和标准错误 echo "Error message" >&2 | tee -a "$LOGFILE" 2>&1
This is less convenient for full-script logging, but useful if you only need to capture output from specific commands.
验证是否生效
To test if it's working, add these lines to your script after setting up the redirection:
echo "This is a test stdout message" echo "This is a test stderr message" >&2
Run the script, then check both your terminal and the log file—both messages should appear in both places.
内容的提问来源于stack exchange,提问作者Aravind raj

