Just Enough vi to Get By
There are a lot of great vi tutorials on the web. They all have one common flaw: they assume you want to learn vi. This article assumes you don't (or at least that you'd like to get some work done while you're doing so).
Because vi is the default Unix editor, users can wind up having to use it like it or not. Where upstream defaults to
vi, Arch does as well. While it is possible to figure out which environment variable a program is looking to and override it, it is often easier just to buckle down and use vi.
This is even more important since a number of the programs which default to
vi represent the safest way to edit certain very important (and very dangerous) files. This includes
sudo -e. See this blogpost for a summary of these programs and the importance of using the right tool to edit them.
The purpose of this page is to teach just enough vi to allow casual editing of config files. Everything in these examples can be done "better" using other features of vi, but this is the minimum you need to know to survive. It will give you functionality about equivalent to nano.
The most confusing thing about vi is the modes: editing and command. Depending on which mode you are in, typing letters will either input text (editing mode) or give navigation, search or other commands (command mode). And just to make it even better, by default there is no visual cue as to what mode you're in.
That problem is easily solved. The first thing you do after vi opens your file is type:
Nothing will happen. That is because you are in command mode and showmode only shows the editing modes. When you enter an editing mode, showmode will display that fact in the lower right hand corner of your terminal.
In command mode, there are two sorts of commands—single letters and commands (single or multiple letters) preceded by a colon (
:) as seen above.
First off, backup your config files before you edit them. In general, and especially before you start playing with vi. vi has extremely limited ability to undo mistakes. Back up your files.
Here's how to discard all changes since your last save--in command mode type
Changing Modes and Adding Text
To get into editing mode and add text, in command mode hit
a. This will put you in editing mode with the cursor after where the character on which it was resting while you were in command mode.
Now type whatever it is you want to type. Once you are done, get out of editing mode and into command mode.
To get out of editing mode, hit
Esc. In fact, before you do anything in command mode hit
Esc just to make sure you're in command mode. Feel no shame: there are plenty of experienced vi users who pound on the
Esc key like fury chimps. Just to be sure.
Moving the Cursor
Movement is done in command mode. You can use the arrow keys on your keyboard to move around.
In edit mode you may not be able to use your arrow keys to move around. Worse yet, using your arrow keys may actually output A, B, C or D. Repeatedly. Get out of edit mode before trying to move.
You can make the arrow keys work in editing mode by changing your $TERM variable to "ansi" using
$env TERM=ansi vi FileYouAreEditing.conf
or if you were editing
$sudo env TERM=ansi visudo
Moving within the File
To move down one screen
Ctrl+f and to move back one screen
To delete a character use the delete key. Backspace will not work.
In order to insert text you need to leave command mode and enter editing mode.
Move the cursor to the last character ahead of where you want to insert text. Type the letter
a. If you
:set showmode (see above), in the lower right hand corner of your screen it will show
Type in your text and then hit the
Esc key once you are done. If you set showmode (see above), there will no longer be any mode indication in the lower right of your screen. Until you do type
Esc and get out of editing mode, you cannot give any commands or move—just input text.
Inserting New Blank Lines
Enter editing mode using
a and hit
In a typical editor you'd go to the end of the line and hit
Del or the start of the line and hit
Backspace. Unfortunately that won't work in vi.
To join two lines in vi, you
- enter command mode by hitting
- navigate to the first of the two lines you want to join
To join multiple lines in vi, you
- turn on line numbers
- type in the following, substituting the line number of the first line you want to join and the line before the last line you want joined for x and y
- note that the
jis lower case
Cutting and Pasting Whole Lines
To cut an entire line, in command mode type
yy ("y" is for "yank").
To paste the line, in command mode, type
p. This will paste to the line below where the cursor is.
Search and Replace
You need to be in command mode to search. Search works the same way as it does in man pages:
- to search forward, type
/followed by the search pattern, followed by
- to search backward, type
?followed by the search pattern, followed by
- to repeat (in either direction), hit
Search and replace works in a way which is very similar to
- to replace the first instance of "SearchString" on the line you are in, type
:s/SearchString/ReplaceString/cand hit Enter.
- to replace all instances of "SearchString" on the line you are in, type
:s/SearchString/ReplaceString/gcand hit Enter
- to replace all instances of "SearchString" in the entire file you are in, type
%:s/SearchString/ReplaceString/gcand hit Enter
Each of these will ask you to confirm the change.
vi's way of asking for confirmation is not at all intelligible. Basically it will show you the search string with a bunch of carets below it. If you want to make the change, hit
y and Enter, if you don't just hit Enter.
:%s/foo/bar/gc I pity the foo. ^^^
Saving Your Work
To save your work without exiting vi, type
To save and exit, type
An Ounce of Prevention: Editing Your Configuration File
One way to minimize the pain of using vi is to edit its configuration file to automatically fix some of the issues highlighted above.
vi's configuration file is
.exrc and is kept in your
$HOME directory. Here's a sample annotated file:
# sample .exrc # automatically show if vi is in editing mode in lower right hand corner of screen set showmode # automatically show line numbers set number # set terminal type to ANSI (allows use of arrow keys for motion while in edit mode) set term=ansi
|Em dash||—||2014||--- (3 minuses)|
|Left single quote||‘||2018||<'|
|Right single quote||’||2019||>'|
|Left double quote||“||201C||<"|
|Right double quote||”||201D||>"|
|Paragraph Mark (Pilcrow)||¶||00B6||PP|
- under the
transmissionuser but adding the user to the
If you want to run as
transmission but still be able to use the transmission web interface as an ordinary user, as a compromise you can add your user to the
transmission group, change permissions on some of the files and directories in
#usermod -a -G transmission myusername #chmod g+rwx /var/lib/transmission #chmod g+rwx /var/lib/transmission/Downloads #chmod
Systemd Service Files
Systemd has a number of service file options that enhance security. Edit service type database As mentioned above, Avahi comes with a tool that can check the service. avahi-browseAnd avahi-discoverto display a description of the service using the even database files Both. The database contains the names of most services (not all).
Unfortunately, since the QOTD service just created is not included in the database it avahi-browse -awill display the following entry:
+ wlp2s0 IPv4 MyServer _ qotd._ tcp local Get source First github mirror of avahi located in service-type-databasethe sub-directory build-db.inand service-typesplease be placed in the build directory to download the file:
$ wget https://raw.githubusercontent.com/lathiat/avahi/master/service-type-database/build-db.in $ wget https://raw.githubusercontent.com/lathiat/avahi/master/service-type -database / service-types Fix source Next, create the following script:
- ! / bin / bash
sed -e 's, @ PYTHON \ @, / usr / bin / python 2.7, g' \
-e 's, @ DBM \ @, gdbm, g' <build- db.in> build-db
chmod + x build-db The above script build-dbcreates a file named:
$. / whatever_you_named_the_script.sh $ ls build-db build-db.in service-types whatever_you_named_the_script.sh Then service-typesadd a new QOTD service to the file. The file is one entry per line type:Human Readable Descriptionand fills in the entry in the form. The description can contain spaces.
For example, add the following entry at the end of the file:
_qotd._ tcp: Quote of the Day (QOTD) Server Build and install a new database build-dbPlease run python script (use python 2 instead of python 3). service-types.dbThe file is built. gdbmtoolsPlease make sure that the new database can be loaded using the built-in and that new entries are included:
$ /usr/bin/python 2.7 build-db $ ls build-db build-db.in service-types service-types.db whatever_you_ named_the_script.sh $ gdbmtool service-types.db
Welcome to the gdbm tool. Type? For help.
gdbmtool> fetch _ qotd._ tcp Quote of the Day (QOTD) Server gdbmtool> quit Make sure you back up your old database and move the new database so avahi-browsethat new entries are recognized:
$ cp /usr/lib/avahi/service-types.db / backup-directory
- cp /build-directory/service-types.db /usr/lib/avahi/service-types.db
$ avahi-browse -b | grep QOTD Quote of the Day (QOTD) Server avahi-browse The entries for it are as follows:
+ wlp2s0 IPv4 MyServer Quote of the Day (QOTD) Server local reference