Bash脚本未生成预期HTML输出,寻求修改方案
Let's walk through the key issues in your script and how to fix them to get the expected output:
1. Wrong Username Extraction
Your original cut -d" " -f4 was grabbing the timestamp field instead of the username. We'll use awk to correctly pull the username, and map invalid users to <UNKNOWN>:
grep "Failed password for" "$logfile" | awk '{ # Check if this is an invalid user line if ($11 == "invalid") { print "<UNKNOWN>" } else { # Grab the valid username from field 11 print $11 } }' | sort | uniq -c | sort -k1,1nr -k2,2 > templog
(Note: Adjust field numbers if your log format differs—this assumes the username is in field 11 after "Failed password for".)
2. Stop Editing the Original Log File
Remove the sed -i 's/invalid/<UNKNOWN>/g' $logfile line. Modifying log files in place is risky and unnecessary now that we handle invalid users during extraction.
3. Correct HTML Tag Rendering
Your script was writing escaped tags like <html>, which makes browsers display tags as text instead of rendering them. Write raw HTML tags instead:
echo "<html>" > flog.html echo "<body><h1>Failed Login Attempts Report as of `date`</h1>" >> flog.html # ... later ... echo "</body>" >> flog.html echo "</html>" >> flog.html
4. Properly Escape User Content
Escape < and > in usernames to avoid breaking HTML (e.g., <UNKNOWN> becomes <UNKNOWN>):
sed -i 's/</\</g;s/>/\>/g' templog
5. Add Commas to Large Counts
Format numbers with commas for readability using awk:
awk '{printf "%'\''d %s\n", $1, $2}' templog > temp && mv temp templog
6. Fix Closing Body Tag
Change echo "/body" to echo "</body>" to produce valid HTML.
7. Clean Up Temporary Files
Add rm templog at the end to delete the temporary file after generating the report.
Full Corrected Script
#!/bin/sh if [ $# -eq 0 ] then echo "Usage : flog LOGFILE" exit 1 fi logfile="$1" # Extract usernames: map invalid users to <UNKNOWN> grep "Failed password for" "$logfile" | awk '{ if ($11 == "invalid") { print "<UNKNOWN>" } else { print $11 } }' | sort | uniq -c | sort -k1,1nr -k2,2 > templog # Add commas to count numbers awk '{printf "%'\''d %s\n", $1, $2}' templog > temp && mv temp templog # Escape HTML special characters in usernames sed -i 's/</\</g;s/>/\>/g' templog # Prepend line breaks to each entry sed -i 's/^/<br \/> /g' templog # Generate valid HTML file echo "<html>" > flog.html echo "<body><h1>Failed Login Attempts Report as of `date`</h1>" >> flog.html cat templog >> flog.html echo "</body>" >> flog.html echo "</html>" >> flog.html # Show the generated HTML cat flog.html # Clean up temporary file rm templog
Expected Output (HTML Source)
This script will generate a valid HTML file that renders correctly in a browser. The source will look like:
<html> <body><h1>Failed Login Attempts Report as of Thu Dec 25 07:00:00 MST 2014</h1> <br /> 1,325 <UNKNOWN> <br /> 505 root <br /> 17 adm <br /> 16 ftp <br /> 10 apache <br /> 10 mail <br /> 2 backuppc <br /> 2 games <br /> 2 news <br /> 2 squid <br /> 1 bin <br /> 1 nobody <br /> 1 operator <br /> 1 smmsp <br /> 1 sshd</body> </html>
When opened in a browser, this will display a heading followed by each login attempt count on a new line, with <UNKNOWN> for invalid users.
内容的提问来源于stack exchange,提问作者ShreddedSaber

