Bash脚本中diff命令错误信息无法重定向的问题求助
diff Errors in Your Bash Script Hey there! I see the issue with your script — even though you added 2>/dev/null, the error messages from diff are still showing up. Let's break down why that's happening and fix it.
Why Your Current Redirect Isn't Working
Your command looks like this:
Z=`diff -Z $ref_out $exec_out | grep "[<>]" | wc -l` 2>/dev/null
The 2>/dev/null is attached to the entire command substitution, but in practice, it only redirects stderr from the last command in the pipe chain (which is wc). The diff command's error messages are still being sent to the original stderr before the pipe processes them.
Simple Fix: Redirect diff's Stderr Directly
Move the 2>/dev/null right after the diff command so it captures only diff's errors:
Z=$(diff -Z "$ref_out" "$exec_out" 2>/dev/null | grep "[<>]" | wc -l)
A couple of extra improvements here for better bash practice:
- Used
$()instead of backticks () — it's more readable and supports nested command substitutions better. - Quoted
"$ref_out"and"$exec_out"to handle filenames with spaces or special characters (a super common gotcha for bash beginners!).
Alternative: Redirect All Pipe Errors
If you want to suppress errors from all commands in the pipe (though in your case, only diff is likely to throw errors), you can wrap the entire pipe in a command group and redirect stderr once:
Z=$( { diff -Z "$ref_out" "$exec_out" | grep "[<>]" | wc -l; } 2>/dev/null )
The curly braces { ...; } group the commands together, so the 2>/dev/null applies to everything inside.
Bonus: Add File Existence Checks
For a more robust script, you can check if the files exist before running diff — this lets you give a clearer error message instead of silently suppressing it:
# Check if both required files exist if [[ ! -f "$ref_out" || ! -f "$exec_out" ]]; then echo "*** testcase: [ stdout - FAILED ] - Missing reference or output file" exit 1 fi # Now run the diff check safely Z=$(diff -Z "$ref_out" "$exec_out" 2>/dev/null | grep "[<>]" | wc -l) if [ "$Z" -gt 0 ]; then echo "*** testcase: [ stdout - FAILED ]" else echo "*** testcase: [ stdout - PASSED ]" fi
内容的提问来源于stack exchange,提问作者Mihai Paul

