Editing a system file often means checking a hostname, date, or network setting at the same time. You can run those commands, and even capture their output, without leaving vi or Vim. The examples below use Vim on Linux; traditional vi supports the basic features, although prompts and installed external commands can vary.
Start in the right mode
vi and Vim are modal editors, so the same key can do different things depending on the current mode:
-
Normal mode is for moving and running editing commands. Press
Escto return to it. -
Insert mode is for typing text. Press
iin Normal mode to enter it, thenEscwhen you finish. -
Command-line mode is reached from Normal mode with
:. Commands such as:wand the examples below are typed after that colon and finished with Enter.
If Vim seems to ignore your typing or starts changing text unexpectedly, press Esc once or twice before trying again. This small habit prevents many accidental edits.
Run a command with :!command
From Normal mode, type : followed by ! and the command. For example, open the original guide's example file with:
sudo vi /etc/hosts
Then run a quick check from within the editor:
:!date
:!ip addr
The command runs through your shell and its output is displayed temporarily; it is not inserted into the file. Follow the prompt (usually pressing Enter) to return to the buffer. This is useful for checking a setting or gathering information before deciding what to edit.
The original article used :!ifconfig while editing /etc/hosts. That is still a valid legacy example on systems that provide net-tools, but ifconfig is omitted on many modern installations. The ip addr command from iproute2 is the usual current alternative. Neither command is expected to modify the hosts file merely because you ran it from Vim.
Insert command output with :r !command
To put a command's standard output into the buffer, use :r !command. The r means read: the output is inserted below the cursor, rather than replacing the current line.
:r !hostname
:r !date -Is
The original hostname example is particularly handy when documenting a server configuration: move the cursor to the desired line, run :r !hostname, and the resulting hostname becomes part of the file. Check the inserted text before saving, especially when the command produces changing or unexpectedly large output. If you only want to see output on screen, use :!hostname instead.
Start a temporary shell with :shell
Sometimes you need several commands rather than one quick check. From Normal mode, run:
:shell
Vim starts the shell named by your $SHELL environment variable. Run the commands you need, then type exit or press Ctrl-D to return to the editor. Your buffer is still there. This is different from quitting Vim, and it is usually more convenient than opening another terminal for a short investigation.
Be aware of privilege boundaries: if you started Vim with sudo, commands and shells started from inside it may also run as root. A safer approach for changing a protected configuration file is often sudoedit /etc/hosts, which edits a temporary copy as your normal user and installs the result with the required privileges.
Open another file without leaving Vim
While editing /etc/hosts, you can open /etc/resolv.conf from Command-line mode:
:e /etc/resolv.conf
The space after :e matters. Vim normally refuses to abandon a buffer with unsaved changes, so save first with :w or use :b to switch between open buffers. Do not add ! to force the operation unless you genuinely intend to discard unsaved work.
Useful buffer commands include:
:buffers
:bnext
:bprevious
:buffers lists open buffers, while the other two move through them. To reload the current file from disk, :e is enough when there are no local changes; :e! deliberately throws those changes away.
Filter lines through a command
The previous examples either display output or insert it. A filter is different: it sends existing text to a command and replaces that text with the command's output. The percent sign represents the whole buffer, so this sorts every line in a file:
:%!sort
That can be useful for a list, but it would be a terrible thing to run on a structured configuration file. For a smaller range, select lines in Visual mode and then type :. Vim inserts the visual range for you:
:'<,'>!sort
You can also use a practical formatter when one is installed. For example, this formats a JSON buffer with Python:
:%!python3 -m json.tool
If the command fails or produces the wrong result, press u in Normal mode to undo the filter before trying anything else. Test destructive-looking transformations on a copy first, and never pipe important text into a command you do not understand.
Save a file you opened without sufficient permission
A common Vim surprise happens after editing a root-owned file as a normal user: :w fails with a permission error. If sudo is available and you are authorized to change the file, this classic workaround writes the buffer through tee:
:w !sudo tee % >/dev/null
Here :w ! pipes the buffer to an external command, while % expands to the current filename. Check the command output carefully before assuming the write succeeded. For routine system administration, prefer opening the file with sudoedit in the first place; it avoids running the whole editor as root and reduces the chance of repeating this emergency workaround.
A safer command-running checklist
- Press
Escbefore entering a:command, especially if you are unsure which mode is active. - Use
:!commandto inspect output,:r !commandto insert it, and a range with!commandto transform existing text. - Use absolute paths for scripts and check output before saving a configuration file.
- Remember that external commands inherit the editor's user and environment.
- Undo an accidental filter with
u; do not save first and hope to fix it later.
If you also need help with movement, searching, copying, splitting windows, or recovering from common Vim mistakes, continue with the Vim survival guide. Together, these techniques turn Vim from a last-resort editor into a practical system-administration workspace.
Top comments (0)