# How to Echo a New Line to File in Bash Without Printing the Literal \n Character

> Learn how to echo a new line to a file in Bash. Discover methods like echo and printf to avoid printing literal n characters and ensure proper newline formatting.

- Repository: [Python/cpython](https://github.com/python/cpython)
- Tags: how-to-guide
- Published: 2026-02-19

---

**Use `echo ""` to append a blank line, or `printf "\n"` for POSIX-compliant newline insertion that never writes literal backslash-n characters to disk.**

Writing actual newline bytes (ASCII 0x0A) to a file in Bash requires distinguishing between escape sequence interpretation and literal character output. The CPython repository’s maintenance scripts demonstrate three reliable patterns that ensure you append true line breaks rather than the visible characters "\" and "n". These techniques work with standard redirection operators and pipeline utilities like `tee`.

## The Empty String Approach (echo "")

The Bash built-in `echo` command automatically appends a single newline to its output, even when passed an empty string. This is the most idiomatic method for inserting blank lines in CPython’s internal tooling.

```bash
echo "" >> target.txt

```

In [`Modules/_decimal/tests/runall-memorydebugger.sh`](https://github.com/python/cpython/blob/main/Modules/_decimal/tests/runall-memorydebugger.sh), the test harness uses this exact pattern to insert visual separation between test sections:

```bash
echo ""

```

This command writes one newline byte and nothing else, avoiding any literal character output.

## The Portable Solution (printf)

For scripts that must run across different shell environments, `printf` offers consistent behavior. Unlike `echo`, `printf` interprets escape sequences such as `\n` and does **not** automatically append an extra newline unless explicitly requested.

```bash
printf "\n" >> target.txt

```

This approach is POSIX-compatible and recommended for maximum portability. The `printf` utility converts the escape sequence into a single line feed byte, ensuring the file receives an actual newline rather than the two-character sequence `\` and `n`.

## The Bash-Specific Flag (echo -e)

When portability is not a concern and you are certain your script runs under Bash, the `-e` flag enables backslash escape interpretation in `echo`:

```bash
echo -e "\n" >> target.txt

```

**Warning:** This flag is not consistently implemented across all shell implementations. The CPython codebase generally avoids `echo -e` in favor of `printf` for this reason, reserving it only for internal developer scripts where Bash is guaranteed.

## How CPython Handles Newlines in Bash Scripts

The CPython repository contains concrete examples of these patterns in production maintenance scripts.

### Status Logging with Implicit Newlines

In [`Tools/wasm/emscripten/browser_test/run_test.sh`](https://github.com/python/cpython/blob/main/Tools/wasm/emscripten/browser_test/run_test.sh), the script logs installation steps using standard `echo`, which automatically terminates each message with a newline:

```bash
echo "Installing node packages" | tee test_log.txt

```

The `tee` command writes the output to both the terminal and the log file, preserving the implicit newline that `echo` appends.

### Explicit Blank Lines in Test Harnesses

The memory debugger test runner in [`Modules/_decimal/tests/runall-memorydebugger.sh`](https://github.com/python/cpython/blob/main/Modules/_decimal/tests/runall-memorydebugger.sh) demonstrates inserting empty lines for readability:

```bash
echo ""

```

This creates visual separation in output logs without risking the injection of literal escape characters.

### Avoiding Literal Escapes in Refresh Scripts

The [`Modules/expat/refresh.sh`](https://github.com/python/cpython/blob/main/Modules/expat/refresh.sh) script performs complex text manipulation where literal `\n` sequences would corrupt the source code. While it uses `sed` with embedded newlines for some operations, it relies on `printf` for straightforward newline insertion to avoid escaping issues:

```bash
sed -i 's/#  define Expat_External_INCLUDED 1/&\n\/* … */'

```

This pattern ensures the substitution inserts an actual newline byte at the specified position, not the literal characters `\n`.

## Summary

- **Use `echo ""`** for simple blank line insertion in Bash-specific scripts, as seen in CPython’s test harnesses.
- **Use `printf "\n"`** for POSIX-compliant, portable scripts that must run across different shell environments.
- **Avoid `echo -e`** unless you control the execution environment, due to inconsistent cross-platform behavior.
- **Reference implementations** in the CPython repository at [`Tools/wasm/emscripten/browser_test/run_test.sh`](https://github.com/python/cpython/blob/main/Tools/wasm/emscripten/browser_test/run_test.sh) and [`Modules/_decimal/tests/runall-memorydebugger.sh`](https://github.com/python/cpython/blob/main/Modules/_decimal/tests/runall-memorydebugger.sh) demonstrate these patterns in production use.

## Frequently Asked Questions

### Why does my file show the literal characters \n instead of a new line?

This occurs when escape sequences are not interpreted by your command. Raw `echo` without flags treats `\n` as two literal characters. To generate actual line breaks, use `printf "\n"` or ensure your `echo` implementation supports and uses the `-e` flag, though `printf` is the more reliable choice according to the CPython source code.

### Is printf better than echo for writing newlines?

**Yes**, for portability. `printf` is POSIX-mandated and behaves consistently across Bash, Dash, Zsh, and other shells. The `echo` command varies between systems—some implement `-e` automatically, others require the flag, and some ignore it entirely. The CPython maintenance scripts prefer `printf` for any operation requiring explicit newline control.

### How do I append multiple newlines to a file?

Repeat the escape sequence in `printf` or call `echo ""` multiple times. For example, `printf "\n\n\n" >> file.txt` writes three newline bytes. Alternatively, use a loop or multiply the string: `printf "%s" "$(printf '\n%.0s' {1..3})" >> file.txt` for a specific count.

### Can I use these methods in POSIX sh scripts or only bash?

`printf "\n"` works in any POSIX-compliant shell including `sh`, `dash`, and `ksh`. However, `echo ""` behavior is standardized enough for newlines in modern POSIX shells, though `printf` remains the safer choice for complex formatting. Avoid `echo -e` entirely in strict POSIX scripts, as it is not defined by the standard.