Reading and editing files: less, tail -f and vim
-
Phase 0: Before you start
-
Phase 1: The origins and OS architecture
-
Phase 2: Day-to-day administration and the command builder
-
Phase 3: Enterprise infrastructure and storage
-
Phase 4: Troubleshooting step by step
-
Phase 5: Final project and career
These vim editor basics are the skill that lets you fix a server from any terminal, because vi or vim is on almost every Linux machine you’ll ever log in to, including the rescue shell on a broken one. Before you edit anything, though, you need to read files well, so this lesson starts with cat, less, head and tail -f, the tools you’ll use to watch logs during every incident.
You’ll learn vim’s modes, how to save and quit (the question everyone asks first), how to search, delete, copy, paste and undo, and how to turn on line numbers. Then you’ll use the habit that separates careful admins from lucky ones: back up the config, edit it, check its syntax with the service’s own test command, and only then restart.
Where this lesson fits
Lesson 12 of 82 in Linux Administration · Phase 1: The origins and OS architecture · Before this: Lesson 11, working with files and folders · Next: Lesson 13, pipes, redirection and quoting
| Time | You need | By the end you can |
|---|---|---|
| About 60 minutes | rocky01 or ubu01 from Lesson 2, and the practice folder from Lesson 11 | Read any file or live log, edit a config in vim without panic, and check it before a restart |
What it is, in one line
You read files with cat, less, head and tail, and you edit them with vim, a modal editor where you switch between a mode for moving and commands and a mode for typing text.
In Simple Words
The ledger and the accountant’s two pens
Picture an old-style shop accountant with a thick ledger. Most of the time he only reads: he flips to a page, runs his finger down to an entry and checks a number. Once in a while he picks up his pen and writes a new entry.
vim works the same way. It starts in a “reading and moving” mode where your keys are commands (go to line 40, find “Port”, delete this line), and you press i when you want to pick up the pen and type, then Esc to put it down again.
Engineer's View
Which tool for which job
| Tool | Best for | Keys and options you’ll use |
|---|---|---|
cat | Short files, a quick look, joining files | -n line numbers, -A show tabs (^I), Windows line endings (^M) and line ends ($) |
less | Anything longer than one screen, including big logs | Space next page, b back, g top, G bottom, /word search, n next match, q quit, +F follow like tail -f |
head | The start of a file | -n 20 first 20 lines |
tail | The end of a file, live logs | -n 50 last 50 lines, -f follow new lines, -F follow even after the log is rotated |
vim / vi | Editing configs and scripts on servers | Modes, :w :q :wq :q!, /search, dd yy p u, :set number |
nano | Quick edits when you’re new | Ctrl+O save, Ctrl+X exit, Ctrl+W search, shortcuts shown at the bottom |
What’s installed differs a little. A Rocky Linux 10 minimal install has vi from the vim-minimal package; the full vim command and vimtutor come with sudo dnf install vim-enhanced. nano is usually there too, but install it with dnf if it isn’t. Ubuntu Server 26.04 ships both vim and nano, and its default editor for tools like visudo and crontab is nano.
vim has more modes than you need on day one. These four cover nearly everything an admin does:
| Mode | How you get there | What your keys do |
|---|---|---|
| Normal | Opening a file, or pressing Esc | Move, delete, copy, paste, undo, search. This is “home” |
| Insert | i (before cursor), a (after), o (new line below), O (new line above) | Type text. The bottom line shows -- INSERT -- |
| Command-line | : from Normal mode | Save, quit, set options, search and replace (:w, :q, :set number) |
| Visual | v (characters), V (whole lines) | Select text, then d to delete or y to copy |
How it works, step by step
The first job is reading, and on a busy server the file you need to read is usually a log that keeps growing. Here is how the reading tools fit around a live log.
1cat dumps the whole file at once
cat prints every byte to your screen and exits. On a 30-line config that’s perfect. On a 2 GB log it floods your terminal for minutes, so for big files you use less, head or tail instead.
2less opens the file one screen at a time
less doesn’t load the whole file first, so it opens a huge log instantly. You can jump to the end with G, search with /, and press q to leave without changing anything. It’s also what man and journalctl use to show you pages.
3tail -f keeps the file open and prints new lines
tail -f prints the last ten lines, then waits and shows every new line the application writes. You run it in one terminal while you reproduce the problem in another. When logrotate renames the log at midnight, tail -f keeps watching the old, renamed file; tail -F notices the new file and switches to it, which is what you want for overnight watching.
4vim opens a copy in memory
When you open a file, vim reads it into a buffer in memory and also creates a hidden swap file next to it (.app.conf.swp) to save your work if the session dies. Your changes touch the real file only when you write with :w. Quitting with :q! throws the buffer away, and the file on disk is untouched.
5Moving between modes
Esc always brings you back to Normal mode, so when you’re lost, press Esc twice. From Normal mode, i takes you into Insert mode to type and : opens the command line at the bottom for save and quit. The diagram below shows the moves you’ll make a hundred times a day.
6The safe edit routine for configs
On a real server the editor is the easy part. A broken sshd_config can lock everyone out, and a broken /etc/sudoers can take away sudo for every admin. So you copy the file first with its permissions kept (sudo cp -a), edit it, run the service’s own syntax check, and keep your current SSH session open until a new login works.
| File | Check before you restart or reload |
|---|---|
/etc/ssh/sshd_config | sudo sshd -t (prints nothing when the file is fine) |
/etc/sudoers and /etc/sudoers.d/* | Edit with sudo visudo, or check a file with sudo visudo -cf <file> |
| Nginx config | sudo nginx -t (Lesson 56) |
/etc/fstab | sudo findmnt --verify and sudo mount -a (Lesson 43) |
| Apache config | sudo apachectl configtest |
Hands-on lab: read a live log and edit a config in vim
Before you run any command, double-check it
Read every command twice before you press Enter. Check the target: the server name, the user, the disk or device name, the path and the sizes. These commands are for learning and were tested in our lab, not on your system. At work, run the read-only commands first, follow your change process, make sure a backup exists, and ask a second person to check anything that changes or deletes data. You run them at your own risk.
You’ll read a test file in different ways, watch a live log, then edit a small config in vim from start to finish. Every file in this lab lives in ~/lab12 except the log you watch, which the system writes for you.
1Make a test config and a long file
Paste this whole block:
mkdir -p ~/lab12 && cd ~/lab12
printf '%s\n' '# demo app config' 'listen_port = 8080' 'log_level = info' 'max_clients = 200' 'data_dir = /srv/app/data' > app.conf
seq 1 100 | sed 's/^/line /' > big.txt
cat -n app.confYou should see this:
1 # demo app config
2 listen_port = 8080
3 log_level = info
4 max_clients = 200
5 data_dir = /srv/app/datacat -n numbers every line, which helps when someone on a call says “look at line 4”. The other two commands built a 100-line file so you have something to scroll through.
✅ Checkpoint: app.conf shows five numbered lines.
2Read the start and the end
Run this:
head -n 3 big.txt
tail -n 2 big.txtYou should see this:
line 1
line 2
line 3
line 99
line 100On a large log, tail -n 100 is usually the first thing you run, because the newest lines are at the bottom.
✅ Checkpoint: You saw lines 1 to 3 and lines 99 and 100.
3Page through a file with less
Run this:
less big.txtInside less, press Space a few times, then G to jump to line 100 and g to jump back to the top. Type /line 42 and press Enter to search, n for the next match, and q to quit. Nothing you press inside less can change the file.
Try the same keys on a real log: sudo less /var/log/messages on rocky01 or sudo less /var/log/syslog on ubu01. Press Shift+F inside less to follow new lines like tail -f, and Ctrl+C to stop following.
✅ Checkpoint: You found line 42 with / and left less with q.
4Spot hidden characters
Run this:
printf 'a\tb \r\n' > win.txt
cat -A win.txtYou should see this:
a^Ib ^M$^I is a tab, the space before ^M is a trailing space, ^M is a Windows carriage return and $ marks the end of the line. A script copied from a Windows laptop with ^M on every line fails with confusing errors, and cat -A shows you why in one second.
✅ Checkpoint: You can name what ^I, ^M and $ mean.

5Watch a log live with tail -f
Open a second SSH session to the same VM. In the first one, start watching the system log:
| On Rocky Linux / RHEL | On Ubuntu |
|---|---|
| |
In the second session, write three test lines into the log:
Run this:
for i in 1 2 3; do logger "health check $i"; sleep 5; doneOn ubu01 the first session should show something like this:
2026-10-27T11:02:14.218733+05:30 ubu01 student: health check 1
2026-10-27T11:02:19.224961+05:30 ubu01 student: health check 2
2026-10-27T11:02:24.231508+05:30 ubu01 student: health check 3On rocky01:
Oct 27 11:02:14 rocky01 student[2214]: health check 1
Oct 27 11:02:19 rocky01 student[2219]: health check 2
Oct 27 11:02:24 rocky01 student[2224]: health check 3The lines appear five seconds apart, as they’re written. Ubuntu prints the RFC 3339 timestamp (date, time with microseconds and the time zone), Rocky still uses the traditional format. Press Ctrl+C to stop tail; it doesn’t touch the log.
No such file? Some trimmed-down installs leave out rsyslog, so only the journal has the logs. Follow it with sudo journalctl -f instead, or install rsyslog (sudo dnf install rsyslog or sudo apt install rsyslog).
✅ Checkpoint: All three “health check” lines appeared in the tail window while the loop ran.
6Open the file in vim and find your way around
On rocky01, install the full vim first (it also gives you vimtutor): sudo dnf install -y vim-enhanced. ubu01 already has it.
Run this:
vim app.confYou’re in Normal mode. Type :set number and press Enter to show line numbers. Move with the arrow keys (or h j k l), press gg for the first line and G for the last, and type :2 and Enter to jump to line 2.
Search with /max and Enter.
✅ Checkpoint: Line numbers show on the left and the cursor sits on the max_clients line.
7Change a value, add a line, save
Still in vim, do these in order:
| Keys | What happens |
|---|---|
:2 then Enter | Cursor goes to line 2 (listen_port) |
$ then x four times | Jump to the end of the line and delete “8080” one character at a time |
a, type 9090, then Esc | Append after the cursor, type the new port, back to Normal mode |
G then o | Go to the last line and open a new line below it in Insert mode |
Type log_dir = /srv/app/logs, then Esc | Your new line is in the buffer |
:w then Enter | Write the file to disk |
The bottom line of vim should show something like this:
"app.conf" 6L, 121B written6L and 121B are the new line and byte counts. Now quit with :q and check the file from the shell:
cat app.conf# demo app config
listen_port = 9090
log_level = info
max_clients = 200
data_dir = /srv/app/data
log_dir = /srv/app/logs✅ Checkpoint: cat shows listen_port = 9090 and the new log_dir line.
8Delete, copy, paste and undo
Run this:
vim app.conf| Keys | What happens |
|---|---|
:4 Enter, then dd | Delete line 4 (max_clients). It’s held in a register, like a cut |
u | Undo. The line is back. Ctrl+R redoes |
yy then p | Copy (yank) the current line and paste it below, so the line now appears twice |
:q | vim refuses: E37: No write since last change (add ! to override) |
:q! | Quit and throw away every change since the last save |
You’ll see E37 in the bottom line because the pasted line is in the buffer but not in the file. (If you had undone every change, vim would let plain :q through.) :q! is your emergency exit whenever an edit goes wrong.
Check the file did not change:
cat app.conf✅ Checkpoint: app.conf still has six lines with listen_port = 9090.
9Edit a system file the safe way
Now the full routine on a real config. You’ll add a harmless comment to the SSH server config, check it and keep the backup.
Run this:
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F)
sudo vim /etc/ssh/sshd_configPress G, then o, type # Lesson 12 test edit, press Esc and save with :wq. Then test the file:
sudo sshd -t && echo "sshd config OK"
ls -l /etc/ssh/sshd_config*You should see something like this (on rocky01):
sshd config OK
-rw-------. 1 root root 3667 Oct 27 11:20 /etc/ssh/sshd_config
-rw-------. 1 root root 3644 Oct 21 09:14 /etc/ssh/sshd_config.bak.2026-10-27sshd -t printed nothing, so the && let the echo run. The backup kept the original owner, mode and date because of cp -a. A comment needs no restart, but for a real change you’d now reload sshd and test a new login from a second terminal before closing the first.
The same idea for sudo: never open /etc/sudoers with a plain editor. sudo visudo edits a temporary copy and refuses to save a broken file. You’ll write your own sudo rules in Lesson 16.
✅ Checkpoint: sshd -t reports OK and a dated backup of sshd_config exists.
10Learn the rest with vimtutor
Run this:
vimtutorvimtutor opens a practice copy of a lesson file and walks you through moving, deleting, changing and searching, in about 30 minutes. Do it once now and once again next week; after that, vim stops feeling strange.
✅ Checkpoint: You finished at least Lesson 1 and 2 of vimtutor.
Break It, Then Fix It
Take a VirtualBox snapshot first (call it “before-lesson12-break”). The second step edits sudoers, and if you get that wrong without visudo, sudo stops working until you fix it as root.
1Save a file you are not allowed to write
Run this, without sudo:
vim /etc/hostsMake any change (press o, type # test, press Esc) and save with :w.
You’ll get this in the bottom line:
E45: 'readonly' option is set (add ! to override)vim noticed you can’t write the file and opened it read-only. If you force it with :w!, you get the real refusal from the kernel:
E212: Can't open file for writingFix: quit without saving, and open it again with sudo.
:q!
sudo vim /etc/hostsIf you’ve typed a lot and don’t want to lose it, there’s a well-known rescue: :w !sudo tee % > /dev/null pipes the buffer to sudo tee, which writes the file as root (Lesson 13 explains tee). Then :q!. For this test, quit without saving.
✅ Checkpoint: You left vim with :q! and /etc/hosts is unchanged (check with tail -n 2 /etc/hosts).
2A typo in sudoers
Here you’ll make a broken sudo rule in a test file, never in the real sudoers, and let visudo catch it.
Run this:
printf 'student ALL=(ALL ALL\n' > /tmp/sudoers.test
sudo visudo -cf /tmp/sudoers.testYou’ll get something like this (classic sudo on Rocky; sudo-rs on Ubuntu 26.04 words it differently):
/tmp/sudoers.test:1:18: syntax error
student ALL=(ALL ALL
^~~The closing bracket is missing. If this line were saved straight into /etc/sudoers with a normal editor, every sudo command would fail with a parse error, including the one you’d need to fix it. On Rocky you could still log in as root; on Ubuntu root is locked, so you’d need the recovery boot.
Fix: correct the line and check again.
printf 'student ALL=(ALL) ALL\n' > /tmp/sudoers.test
sudo visudo -cf /tmp/sudoers.test
rm /tmp/sudoers.testYou should see:
/tmp/sudoers.test: parsed OK✅ Checkpoint: visudo -cf says parsed OK, and you deleted the test file.
3The swap file warning
Open app.conf in vim in your first SSH session and leave it open after making one change (press x). In the second session, open the same file:
Run this in the second session:
vim ~/lab12/app.confYou’ll get something like this:
E325: ATTENTION
Found a swap file by the name ".app.conf.swp"
owned by: student dated: Tue Oct 27 11:31:08 2026
file name: ~student/lab12/app.conf
modified: YES
user name: student host name: rocky01
process ID: 2307 (STILL RUNNING)
While opening file "app.conf"
dated: Tue Oct 27 11:16:52 2026
...
Swap file ".app.conf.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort:vim found the other session’s swap file. On a shared server this is often a colleague editing the same config right now, and two people saving the same file means one of them loses their change without any warning.
Fix: press Q here, then go back to the first session and quit it properly.
Q
(in the first session) :q!If “STILL RUNNING” is missing, the earlier session crashed. Then open with vim -r app.conf to recover, save, and delete the leftover .app.conf.swp so the warning stops.
✅ Checkpoint: ls -a ~/lab12 shows no .app.conf.swp file.
This happened at work
Two admins, one config file
My team lead at an engineering university in Noida tells this one every time a new joiner asks why we fuss about swap files. It was the week before semester exams, and the student portal kept rejecting logins for anyone whose roll number started with 23.
Two admins were working the ticket from different rooms. Both opened the same PAM-related config on the authentication server in vim. The first fixed the filter, saved and restarted the service, and logins worked for about ten minutes.
The second admin had pressed “Edit anyway” at the swap file warning without reading it, fixed a different line, and saved over the file with his older copy, which undid the first fix.
They spent the next hour convinced the service was “reverting by itself” and even suspected a configuration management tool. The real cause turned up only when someone compared the file with the dated backup and saw two different edits, one of them gone. The swap file screen had warned them, naming the other user and the PID.
After that the team agreed on three rules: one person edits a given server during an incident and says so in the chat, every edit starts with a dated cp -a backup, and nobody presses E at the ATTENTION screen without first finding out who owns that PID. Config files that matter went into Git so changes have a name attached.
Common mistakes and troubleshooting
| Mistake | What happens | What to do instead |
|---|---|---|
| Running cat on a huge log | The terminal floods for minutes and you lose your place | Use less, tail -n 100 or grep |
| Using tail -f overnight on a rotated log | You keep watching the old file and miss everything after midnight | Use tail -F or journalctl -f |
| Typing text while vim is in Normal mode | Letters run as commands and lines get deleted or moved | Press Esc twice, then u to undo, and look for -- INSERT -- before typing |
| Editing a config without a backup | No quick way back when the service won’t start | Run sudo cp -a file file.bak.$(date +%F) first |
| Editing /etc/sudoers with a plain editor | One typo breaks sudo for every admin | Use sudo visudo or sudo visudo -f /etc/sudoers.d/<name> |
| Restarting sshd without sshd -t | A typo stops sshd and new logins fail | Run sudo sshd -t and keep a session open while you test |
| Pressing “Edit anyway” at the swap warning | Two people overwrite each other’s changes | Find out who owns the PID first, or press Q |
Interview questions
Click a question to open it. Each one is written the way an interviewer would ask it. Under it you will see why they ask it and one way you could answer, in your own words.
Fresher level
1. You’re in vim, you’ve made a mess of the file and you want out without saving. What do you type?
Why they ask this: It’s a simple question, but freezing on it tells them you haven’t edited files on real servers. They also listen for whether you know about Esc and modes.
How you might answer: I press Esc to make sure I’m in Normal mode, then type :q! and Enter, which quits and throws away every change since the last save. If I want to keep my work it’s :wq.
If I’d only made one bad change, I’d press u to undo it instead and carry on.
2. How would you watch an application log while a user reproduces a problem?
Why they ask this: They want a practical answer with the right tool and a hint that you know logs get rotated.
How you might answer: I’d run sudo tail -F on the application’s log file, or journalctl -u <service> -f if it logs to the journal, and ask the user to try again while I watch. With capital F, tail keeps following when the log is rotated.
If the log is busy I’d pipe it through grep for the user’s ID or the error word so I only see the lines that matter.
2–5 years experience
3. Walk me through how you change a setting in sshd_config on a production server.
Why they ask this: They’re testing change discipline and whether you’ve ever locked yourself out. They want backup, validation and a safe test of new logins.
How you might answer: I take a dated backup with sudo cp -a, make the change with sudo vim, and run sudo sshd -t, which prints nothing if the file is valid. Only then do I reload sshd.
I keep my current session open and test a fresh login from another terminal before I close anything, and if it fails I copy the backup back and reload. The change and the backup file name go into the ticket.
4. Why does visudo exist? Couldn’t you edit /etc/sudoers with any editor?
Why they ask this: They want to see that you understand the risk of a broken sudoers file and the protection visudo adds.
How you might answer: You could, but if you save a syntax error, sudo refuses to run at all, and on a server where root login is disabled that means nobody can fix it without a console or a rescue boot. visudo edits a temporary copy, checks the syntax and refuses to install a broken file.
For drop-in files I use sudo visudo -f /etc/sudoers.d/name, and in automation I validate with visudo -cf before moving the file into place.
Senior level
5. Two engineers keep overwriting each other’s config changes during incidents. How would you stop that?
Why they ask this: They’re looking for process and tooling, not only “be careful”. Good answers include ownership, version control and configuration management.
How you might answer: In the short term I’d make one person the hands on a given server during an incident and have them say so in the incident channel, and I’d teach everyone to read vim’s swap file warning instead of pressing Edit anyway. Every edit starts with a dated backup.
For the long term, the important configs go into Git and get deployed by Ansible or a similar tool, so manual edits are rare, every change has an author and a diff, and a rollback is a revert.
6. A config change caused an outage and the engineer says he only “fixed a typo”. How do you find out what changed?
Why they ask this: They want to see how you collect evidence calmly. Comparing files and checking timestamps and logs are the core.
How you might answer: I compare the current file with the backup or the version in Git using diff -u, which shows the changed lines. If there’s no backup, I check stat for the modify time, the sudo log in the journal for who ran the editor, and the package’s default file with rpm -V or the original in the package cache.
Then I write it up without blame and add the missing guard, usually a syntax check step in the runbook or a pipeline check before deploy.
Quick quiz
Q1. You open a file in vim and want to start typing before the cursor. Which key do you press?
- Esc
- i
- :
- v
Show answer
B — i enters Insert mode before the cursor. a inserts after it, o opens a new line below.
Q2. Which vim command saves the file and quits?
- :q!
- :w
- :wq
- :x!
Show answer
C — :wq writes and quits. :q! quits without saving and :w saves without quitting.
Q3. A log is renamed by logrotate at midnight. Which command keeps following the new file?
- tail -f
- tail -F
- less
- cat -A
Show answer
B — tail -F follows the name and reopens it after rotation; tail -f keeps reading the old renamed file.
Q4. What does cat -A show as ^M at the end of a line?
- A tab
- A trailing space
- A Windows carriage return
- A missing newline
Show answer
C — ^M is the carriage return from Windows CRLF line endings, a common cause of broken scripts.
Q5. What is the safest way to change a sudo rule?
- Edit /etc/sudoers with nano
- Use sudo visudo (or visudo -f for a drop-in)
- Copy a sudoers file from another server
- Edit it as root with vi and restart sudo
Show answer
B — visudo checks the syntax and refuses to install a broken file, so you never lose sudo because of a typo.
Quick recap
- Use cat for short files, less for long ones, head and tail for the start and end, and tail -F to follow a live log across rotation.
- vim has modes: Normal for moving and commands, Insert for typing (i, a, o), and the : command line for saving and quitting.
- :w saves, :q quits, :wq does both, :q! quits without saving; dd, yy, p and u delete, copy, paste and undo.
- Back up a config with cp -a, edit it, run its own check (sshd -t, visudo -c, nginx -t) and only then reload.
- Read the swap file warning: it usually means someone else is editing the same file.
Next lesson
Lesson 13: Pipes, redirection and quoting → You’ll connect commands with pipes, send output and errors to files or throw them away, write to root-owned files with sudo tee, and learn the quoting rules that keep scripts from breaking.
Further reading: vim editor basics
Want to go deeper into vim editor basics? Run vimtutor and then read the vim help pages online (start with usr_02.txt). The man pages for less and tail cover every key and option, and the visudo manual explains the checks it runs.
You can also see the full plan for this course on the Linux Administration course page.
