1. Introduction

The shell is the main entry point for all but the most obscure embedded Linux distributions. Even in the latter, we should be able to run instructions in some form or another. Further, one of the most universal interactive ways to execute commands is to type them in with a keyboard.

In this tutorial, we discuss interactively-typed shell commands and how to insert a manual newline in the middle of a command. First, we go over the difference between adding a newline and submitting a command. After that, we talk about automatic newline insertion based on syntax. Next, we explore techniques to interactively include a newline within a shell command. Then, we look at command-line editing. Finally, we perform a comparison between different methods of command newline insertion based on the environment.

We tested the code in this tutorial on Debian 12 (Bookworm) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments unless otherwise specified.

2. Newline and Buffer Submission

Running a shell command usually involves two steps at the prompt:

  1. type in the command line within the line buffer
  2. submit the line buffer for execution

Like other major operating systems, Linux uses a newline via the Return (Enter) key to trigger a line buffer submission.

Let’s see an example:

$ printf 'Line 1.\nLine2.\n'[Return]
Line 1.
Line 2.
$

In this case, we use printf for outputting two lines of text. To do so, we enter the command and press Return.

This special role of the newline might present challenges in the same way that filenames with newlines could. Also, sometimes we might want to have a newline as part of the buffer instead of its end and submission signal.

3. Automatically Continue Command on a New Line

Naturally, most major shells can detect basic syntax interactively. Thus, unfinished surrounding constructs start another line instead of submitting the current buffer when Return is pressed:

$ printf 'Line 1.[Return]
> Line 2.[Return]
> '
Line 1.
Line 2.
$

In this case, a > right angle bracket and a space precede each continuation line, but they aren’t part of the final buffer contents when submitting. The prefix might be different for shells other than Bash. Critically, we can’t go back to a previous line from a line starting with >.

The mechanism above is valid for other structures as well:

  • for loop
  • while loop
  • if-else
  • single or double quotes
  • ` backticks
  • () parentheses
  • {} braces (curly brackets)

Notably, the automatic line continuation usually doesn’t work for (square) brackets, since they are either just the [ (test) built-in (Bash) or excluded from the line syntax handling.

In contrast, a semi-automatic way of continuing a command on the next line without preserving the newlines is to escape the newline (Return) character. We do this by inserting a backslash at the end of a line like in this echo example without quotes:

$ echo Line 1.\[Return]
> Line 2.\[Return]
> [Return]
Line 1.Line 2.

In all cases above, we just visually format our command buffer but only preserve the newline characters when they’re within quotes.

Now, let’s see how to actually insert a newline by hand.

4. Insert Newline in a Command

In most shells, we can use caret notation to both insert and display special characters and control sequences.

Notably, as long as the shell supports it, all options for inserting newlines that we look at below allow us to go back through the lines via the Left arrow key.

4.1. Universal Newline

One of the available key combinations that are fairly universal involves the input of Ctrl+V followed by Ctrl+J:

$ echo Line 1.[Ctrl+V, Ctrl+J]
Line 2.[Ctrl+V, Ctrl+J]
Line 1.
[...]Line: command not found
$

Critically, the shell still considers the newline character as a command submission. Because of this, echo only works with Line 1., but Line 2. is seen as its own command and results in an error.

In fact, sh and dash even insert ^J, while [t]csh inserts ^M, all with the same combination. Upon submission of the buffer, ^J and ^M do add a newline to the output.

In other words, we can use Ctrl+V, Ctrl+J to create a script interactively in most shells.

4.2. Zsh

There are two newline combinations specific to the Zsh shell that work just like Ctrl+V, Ctrl+J, which is also available in Zsh:

  • Alt-Return
  • Esc-Return

In most other shells, the combinations above produce and submit a ^[ control sequence inducer (CSI).

Still, we can get the same combinations to work in Bash by adding a line to $HOME/.inputrc:

$ cat $HOME/.inputrc
"\e\C-m": "\026\n"

Here, \026 is ^V (Ctrl+V), while \e is an escape character and \C is a control prefix.

After we modify $HOME/.inputrc, we can either restart the shell or use bind to load the current entries of the file:

$ bind -f $HOME/.inputrc

The latter option doesn’t remove old bindings.

5. Bash and Ksh Command Line Editing

The Bash and Korn shells in particular offer another feature that enables arbitrary edits and insertion of any command:

$ command[Ctrl+X, Ctrl+E]

By using the combination Ctrl+X, Ctrl+E, we tell Bash to perform two actions:

  1. save the current command line content in a temporary file
  2. open the temporary command file in the default text editor

Once ready with any edits, we save our changes and exit the editor. At this point, Bash or Korn runs the temporary file with our command as a shell script and removes it.

Of course, we can add any number of newlines and apply formatting.

6. Major Shells and Newline Insertion Techniques

Often, we only consider a number of shells as major ones in the Linux ecosystem:

  • sh – classic Bourne Shell, rudimentary, POSIX-compliant, and default for UNIX v7
  • [t]csh – C shell, fairly basic, C-like, with tcsh as its expansion
  • bash – Bourne Again Shell, a considerable improvement over sh with many complex features
  • dash – Debian Almquist Shell, simpler and fully POSIX-compliant, unlike bash, mainly meant to replace sh as a more feature-rich default
  • zsh – Z Shell, feature-rich, and the default for the Kali Linux distribution
  • ksh – Korn Shell, POSIX-compliant, yet also feature-rich

Thus, we can create a comparison table of the usual ways to insert a newline and what shell supports which methods:

+-----------------------------------------------------+
|                | sh | csh | bash | dash | zsh | ksh |
|----------------+----+-----+------+------+-----+-----|
| Syntax detect  | +  |  -  |  +   |  +   |  +  |  +  |
|----------------+----+-----+------+------+-----+-----|
| Editor         | -  |  -  |  +   |  -   |  -  |  +  |
|----------------+----+-----+------+------+-----+-----|
| Ctrl+V, Ctrl+J | -  |  -  |  +   |  -   |  +  |  -  |
|----------------+----+-----+------+------+-----+-----|
| Alt-Return     | -  |  -  |  /   |  -   |  +  |  -  |
|----------------+----+-----+------+------+-----+-----|
| Esc-Return     | -  |  -  |  /   |  -   |  +  |  -  |
+-----------------------------------------------------+

Here, a / slash means it’s not supported out-of-the-box but can be added without much effort.

7. Summary

In this article, we discussed ways to insert a newline in a shell command.

In conclusion, there are different methods we can leverage to add newlines interactively within commands, and they mainly depend on the shell in use.