10.3 head and tail: First and Last Lines
Let’s be honest, you don’t always need to read the whole novel. Sometimes you just want to check the first page to see if it’s the right file, or peek at the ending to see if your massive data processing job finally succeeded. That’s where head and tail come in—the Swiss Army knives for the terminally impatient. They are brutally simple, gloriously fast, and probably on your system already.
By default, head will show you the first 10 lines of a file. tail will show you the last 10. It’s the digital equivalent of judging a book by its first and last paragraphs, which, let’s be honest, is a shockingly effective strategy in system administration.
# Show me the first 10 lines of that config file I'm scared of
head /etc/nginx/nginx.conf
# Did the last job write anything to the end of the log?
tail /var/log/my-app.log
Controlling the Output: More or Less
Ten lines is the default because some ancient Unix wizard probably had ten fingers. Thankfully, you’re not stuck with that. The -n option (--lines for the long-form enthusiasts) lets you specify exactly how many lines you want. Need just the first line? head -n 1. Need the last 50? tail -n 50.
# Get the first line (often a header)
head -n 1 massive_dataset.csv
# Get the last 15 lines of a log file to see the most recent errors
tail -n 15 /var/log/syslog
Here’s a pro-tip that feels like a secret handshake: you can use a shorthand. -n 5 and -5 mean the same thing for both commands. It’s one of those beautiful, consistent bits of Unix philosophy that you wish happened more often.
The Killer Feature: tail -f
This is the reason tail is worth its weight in gold. The -f option (follow) is pure magic. It doesn’t just show you the last few lines and quit; it follows the file, outputting new lines as they are written. This is your go-to move for watching log files in real-time. Fire it up, then trigger an event in your application, and watch the errors pour in live. It’s like a reality TV show for your infrastructure.
# Watch the system log live. (Ctrl+C to stop the madness)
tail -f /var/log/syslog
An even more robust version is tail -F (note the capital F). This is useful for log files that get rotated (a common practice where the current log is renamed and a new one is created). -f might stop following if the original file it was watching disappears. -F is smarter; it will happily pick up the new file of the same name and keep on going. Use -F for logs, you’ll thank me later.
Bytes, Not Lines
Sometimes, and I mean very rarely, you care about bytes, not lines. Maybe you’re dealing with a binary file or some deeply cursed output without line breaks. For these dark arts, use the -c (bytes) option.
# Get the first 100 bytes of a file
head -c 100 some_file
# Get the last 1024 bytes (a classic kilobyte!) of a database dump
tail -c 1024 database.sql
Edge Cases and Pitfalls
These tools are simple, but simplicity has its own sharp edges.
Non-Text Files: Using
headortailon a binary file (like an executable or an image) will work, but the output will likely spew unprintable characters all over your terminal, potentially messing up your prompt. You’ve been warned. A quickfile my_unknown_filecan save you a headache.The File is Too Damn Short: If you ask for the last 1000 lines of a 10-line file,
tailwill just politely show you the entire file. It doesn’t get upset or error out. It just gives you what it can. This is the correct behavior.The One Weird Trick: You can combine them. Yes, really. Need lines 10 through 15? You can use
headandtailin a pipeline. First, usehead -15to get the first 15 lines, then pipe that totail -6to get the last 6 of those 15 lines. It feels a bit like a Rube Goldberg machine, but it works.# Get lines 10 through 15 of file.txt head -15 file.txt | tail -6
There you have it. Two of the most frequently used commands in existence. They’re not fancy, they don’t have a million options, they just solve a problem and get out of the way. Learn them, use them, and appreciate the elegant simplicity of a tool that does one job perfectly.