41

I want to edit crontab. It is supposed to be Vi, but it's not, as you can see:

root@euve252628:~# crontab -e

0

0 * * * * /var/www/vhosts/nevemind-what-webs/httpdocs/megacronstunde.php

?

:wq

?

Yes, it gave me a ?. And why does it give me a zero?

When I type a q and press Enter - it quits. I need to know how to save, because it's not classic Vi.

5
  • 5
    Most likely ed: by default, it gives a character count (which in Debian based systems is typically 888 the first time, being the number of characters in the template "empty" crontab). If you're seeing a count of 0, you must have modified that. See Crontab -e command not working properly Commented Sep 11, 2017 at 12:41
  • 31
    ed, man! !man ed: gnu.org/fun/jokes/ed-msg.html
    – juhist
    Commented Sep 11, 2017 at 13:42
  • 6
    @juhist Rather than a comment this should be the answer.
    – dessert
    Commented Sep 11, 2017 at 15:13
  • 1
    While you usually want to just override EDITOR to something else, if you're interested in actually using ed, this is a great introduction: sanctum.geek.nz/arabesque/actually-using-ed Commented Sep 13, 2017 at 18:36
  • @justme, by the way, welcome to StackExchange! If you find an answer that best answers your question, you can accept it by clicking on the checkmark next to it.
    – JoL
    Commented Sep 15, 2017 at 17:35

4 Answers 4

65

That's ed

By default its prompt is the empty string. If you want to quit, just enter q. Don't prefix with :. If you have unsaved changes, it will reply with ?. You can interpret that as "are you sure?", and confirm by commanding q again. By the way any command it doesn't understand will also cause it to reply ?. That's the only error message it knows.

Its commands are what vim/vi/ex/sed is based on, so commands like g/re/p, %s/vi/&m/g, 1,3d, /pattern/,$d, w, q, wq work just like vim.

Commands like i, a, and c go into insert mode. To leave insert mode and go back to command mode, just enter a line that has only a .. To "move" to another line, just enter the line number, an offset from the current line like +2 or -1, or a regex as a command to go to that line. . means current line in command mode. You can use it to know where you're at. $ means last line.

By the way, if you want to learn more about it, this being a GNU program in linux, most of its documentation is in info ed instead of man ed.

Here is an example session, with comments added (not accepted by ed):

$ ed
i                    # insert (on current line)
vi
.                    # end insert
%s/vi/&m/g           # substitute vi for vim globally in all lines
i                    # insert (on current line)
first line
.                    # end insert
$a                   # append on last line
last line
.                    # end insert
%p                   # print all lines
first line
vim
last line
2                    # move to line 2 and print it
vim
/line                # move forward to line matching /line/ and print it
last line
-1                   # move 1 line backwards and print it
vim
?line                # move backward to line matching /line/ and print it
first line
+1                   # move 1 line forward and print it
vim
g/line/p             # print lines matching /line/ (grep)
first line
last line
p                    # print (current line)
last line
.                    # move to current line and print it
last line
c                    # change (current line)
final line
.                    # end insert
%p                   # print all lines
first line
vim
final line
/vim/,$c             # change from line matching /vim/ to last line
that's all
.                    # end insert
%p                   # print all lines
first line
that's all
wq                   # write and quit
?                    # write what?
h                    # help with last error message
No current filename
wq                   # write and quit to check error message
?
H                    # help with all error messages
No current filename
wq                   # write and quit to check error message
?
No current filename
wq file.txt          # write file.txt and quit
22                   # wrote 22 bytes

EDIT: Like grawity mentions, more helpful error messages can be activated with h or H. Also, , rather than % in the range part of a command is the official way to refer to "all lines" in ed. In GNU ed, the possibility to use % for this is supported but not mentioned in the info manual. Use of % for all lines was apparently invented by ex, seemingly because, there, , means .,. rather than 1,$ like in ed.

EDIT2: Setting a different editor

Like other answers mentioned, if you want to specify a different editor, you can do so by setting the EDITOR or VISUAL environment variables. The difference between the two is explained in this answer.

You can do so like this if you want to set it for a single command:

EDITOR=vi crontab -e

or like this if you want all programs launched in the shell session to use it:

export EDITOR=vi
crontab -e

You can save the export in ~/.profile or /etc/profile, depending if you want it to be a user or system setting for bash, respectively. That's the unix portable way to set the editor; you can do this in any distribution.

In Ubuntu, there is also the update-alternatives command. The current default editor can be seen with update-alternatives --display editor, and you can use update-alternatives --config editor to set it:

$ sudo update-alternatives --config editor
There are 4 choices for the alternative editor (providing /usr/bin/editor).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /bin/nano            40        auto mode
  1            /bin/ed             -100       manual mode
  2            /bin/nano            40        manual mode
  3            /usr/bin/vim.basic   30        manual mode
  4            /usr/bin/vim.tiny    10        manual mode

Press enter to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in manual mode.
6
  • 2
    Modern versions know English error messages, you just need to use h to ask for them (or H to permanently enable it).
    – user1686
    Commented Sep 13, 2017 at 13:00
  • 2
    (Also, % appears to be an ex invention. Officially ed uses , to mean all lines, even though some versions accept % as well.)
    – user1686
    Commented Sep 13, 2017 at 13:00
  • This is correct but should also mention the EDITOR and VISUAL environment variables. Commented Sep 14, 2017 at 0:35
  • Most of the commands in ed are the same as in vi, except you don't have to press ":" first to get out of graphic editing mode. I learned Unix when "real programmers" didn't waste time using GUIs - an 80x25 "green screen" terminal works nearly as well as an IBM 029 card punch for editing, but not quite ;)
    – alephzero
    Commented Sep 14, 2017 at 7:03
  • @chrylis EDITOR and VISUAL aren't really that relevant. The question was basically: what is this editor, and how do I use it? (what is this 0 and this ?, and how do I save?).
    – JoL
    Commented Sep 14, 2017 at 13:59
39

How to find out what this editor is

Press Ctrl+Z. This suspends the editor and gives you a shell prompt. At the prompt, run ps to see what processes are running in this terminal.

bash-4.3$ crontab -e
1077
^Z
[1]+  Stopped                 crontab -e
bash-4.3$ ps
  PID TTY          TIME CMD
26295 pts/10   00:00:00 bash
26297 pts/10   00:00:00 crontab
26298 pts/10   00:00:00 sh
26299 pts/10   00:00:00 ed
26302 pts/10   00:00:00 ps

bash is the original shell, crontab is expected, sh is another shell which must have been invoked by crontab, and ps is the running ps command. That leaves ed (provided by the package of the same name).

If you can't figure out how to quit the editor, you can kill it at this point, with kill 26302 or kill %1.

What is ed?

Ed is an ancient editor, dating back from before monitors were a (commonplace) thing. It was designed for computers whose interactive output peripheral was a teleprinter.

The 0 it displays at the beginning is the number of lines in the file. Evidently that's important information.

? means that ed didn't understand what you typed. Line printers are slow, so ed doesn't waste time and ink to display pointless information such as error messages. An old joke (I don't know the origin) goes:

Ken Thompson has an automobile which he helped design. Unlike most automobiles, it has neither speedometer, nor gas gauge, nor any of the other numerous idiot lights which plague the modern driver. Rather, if the driver makes a mistake, a giant “?” lights up in the center of the dashboard. “The experienced driver,” says Thompson, “will usually know what’s wrong.”

If you feel inexperienced, you can issue the command H (all commands but one are a single letter (not counting data arguments), because who likes typing), and you'll get error messages. For example, if you just press Enter

?
H
Invalid address

Clear, isn't it? (An empty line is the empty command — the one that isn't a single letter. The empty command moves to the next line and prints it. If you're at the end of the file, which is always the case in an empty file, there is no next line, so the address to which you requested to move is invalid.)

How to get another editor

The crontab command, like most commands that run a text editor, check the environment variables VISUAL and EDITOR (in that order) to decide which program to run, falling back to a system default. If either of these variables is set to ed, change it or remove it.

On Ubuntu (and Debian and others), the system default editor is /etc/alternatives/editor, which is managed through the alternatives mechanism. By default it picks the “best” editor that's installed, where “best” is defined by priorities set by package maintainers. Use update-alternatives to configure an alternative. You can display the available editors and their priorities with

update-alternatives --display editor

ed has the priority -100, whereas all the other “sensible” editors have a positive priority, so the only way it would be used by default is if no editor has been installed. A default installation of Ubuntu uses nano as the default editor, with priority 400. If the alternative has been set to ed, you can change it with

sudo update-alternatives --config editor
9
  • Gilles, Shouldn't On Ubuntu (and Debian and others), the system default editor is /etc/alternatives/editor be rephrased to On Ubuntu (and Debian and others), the system default editor is /usr/bin/editor?
    – heemayl
    Commented Sep 12, 2017 at 8:38
  • quite comprehensive (except it doesn't mention EDITOR env variable? but maybe on purpose, so that people use the proper way to set it on the system via update-alternatives). Maybe change however : ps with pstree -sap $$ ? (easier to figure out which editor was launched, as it is now in a tree format) Commented Sep 12, 2017 at 9:23
  • @heemayl /usr/bin/editor is a symlink to /etc/alternatives/editor. The fact that applications call /usr/bin/editor is a detail that I skipped. Commented Sep 12, 2017 at 10:20
  • 3
    @OlivierDulac I do mention EDITOR and VISUAL. They are in fact the proper way to choose an editor since this is a user preference, not a system-wide preference. I prefer to stick to ps here to keep things simple. Commented Sep 12, 2017 at 10:21
  • 1
    "... computers whose interactive output peripheral was a line printer." A line printer was not an interactive device - it was a relatively high speed (and expensive) device for producing large amounts of printed output. You mean "a printing terminal with a keyboard", like a teletype (which could also work as a punched paper tape I/O device) or an IBM "golfball" typewriter.
    – alephzero
    Commented Sep 14, 2017 at 7:10
12

From your question it seems like your default EDITOR is not vim, and you have problems with the current default editor.

The below command will set the default EDITOR to be vim

export EDITOR=vim

After setting the default editor to be vim, running crontab -e will use vim as your editor.

Notes:

  1. If you prefer, you can choose different EDITOR as your default editor
  2. If you want to set the default editor to vim permanently, you'll have to add the above command to your ~/.bashrc or ~/.profile or similar file.
4

To use VI editor to edit crontab, use the below command.

EDITOR="vi" crontab -e

or, if you want to edit with another editor like gedit, nano, etc., just replace vi with the editor name.

3
  • Thanx a million! With the EDITOR="vi" crontab -e it works.
    – justme
    Commented Sep 11, 2017 at 14:21
  • 3
    @gronostaj This is not the same as any other answer that has been posted here. Setting an environment variable for a single run of a single command is not the same as exporting it for all subsequent commands run from the current shell instance. That answer is useful for changing the setting permanently, but for controlling the editor per-run, this is the correct answer. Commented Sep 11, 2017 at 18:26
  • 3
    Indeed, knowing how to prepend environment variables on the command line is very important, as changing the variable permanently might be undesirable. One of the subtle strengths of the *nix shells is the ability to do this so easily. Commented Sep 11, 2017 at 22:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .