Skip to content
shellmap

Append command output to a file

Add a command's output to the END of a file (creating it if missing) without erasing existing content — for incremental logs, config patches, and accumulators.

How to append command output to a file in each shell

Bashunix
date >> /var/log/app.log

`>>` appends; `>` truncates. Both create the file if missing. To append stderr too: `cmd >> file 2>&1`. To append both via the combined form: `cmd &>> file` (bash 4+, NOT POSIX).

Zshunix
date >> /var/log/app.log
Fishunix
date >> /var/log/app.log
PowerShellwindows
Get-Date | Add-Content /var/log/app.log

`Add-Content` defaults to ASCII on pwsh 5.1, UTF-8-no-BOM on pwsh 6+. Specify explicitly: `-Encoding utf8NoBOM`. Alternative: `Get-Date | Out-File /var/log/app.log -Append` — same effect but Out-File defaults to UTF-16-LE on 5.1 (BOM!).

cmd.exewindows
date /t >> app.log

`>>` appends, `>` truncates — same as Unix. cmd output defaults to system OEM encoding (e.g. CP437 / CP1252) — Unicode characters get mojibake unless you `chcp 65001` first.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • **Race-condition with concurrent writers**: bash `>>` opens the file with `O_APPEND` flag, which the Linux kernel guarantees atomic for writes UP TO `PIPE_BUF` (4 KB on Linux, 512 bytes on POSIX minimum). Concurrent `>>` writes from multiple processes interleave safely if each write is under 4 KB; LARGER writes can interleave mid-write. This is why nginx and apache logs (one line per request, well under 4 KB) work fine with multiple workers — but `cat hugefile >> log` from two processes CAN produce corrupted lines. For larger atomic writes, use `logger` (syslog) or a real log aggregator. pwsh `Add-Content` does NOT use `O_APPEND` — it opens, seeks-to-end, writes, closes; two concurrent `Add-Content` calls CAN lose writes. Use `[System.IO.File]::AppendAllText` with `[FileShare]::Read` to get the same kernel-level guarantee.
  • Encoding pitfalls in pwsh: (1) pwsh 5.1 `>>` redirect defaults to UTF-16-LE with BOM — appending to a UTF-8 file via `cmd >> file` mixes encodings and most readers display garbage starting from the appended line. (2) pwsh 6+ defaults UTF-8-no-BOM for `>>` (matches `Add-Content` defaults) — safer cross-shell. (3) `Out-File -Append` honors `$PSDefaultParameterValues["Out-File:Encoding"]` if set — many CI scripts set this globally to enforce UTF-8. (4) Native exe output piped to `>>` goes through pwsh's stream encoding (`$OutputEncoding`), NOT the file encoding — set `$OutputEncoding = [Console]::OutputEncoding` for byte-faithful capture.
  • Trailing-newline trap: `echo "line" >> file` adds `line\n`. `printf "line" >> file` (no `\n`) leaves the file ending mid-line — next `>>` writes butt up against it. Tools like `wc -l`, `awk`, and most parsers EXPECT files to end with `\n` (POSIX text-file definition); a missing trailing newline causes `wc -l` to undercount by 1, `awk 'END { print NR }'` to also undercount, and `diff` to insert "\ No newline at end of file" markers. Always use `echo` (which adds newline) or `printf "...\n"` (explicit newline) when appending. pwsh `Add-Content "line"` adds the platform line ending (`\r\n` on Windows, `\n` on Linux/macOS) — set `-NoNewline` to suppress.
  • Concurrent rotation: a process appending to `/var/log/app.log` while `logrotate` moves the file (`mv app.log app.log.1; gzip app.log.1`) — the appending process holds the OPEN FILE DESCRIPTOR pointing at the now-renamed inode, and continues writing to the gzipped/renamed file. Bytes are LOST to the log forever. Mitigations: (1) use `copytruncate` directive (logrotate copies the file then truncates the original — preserves the open fd); (2) send SIGHUP to the writer so it reopens (nginx, apache, syslog do this); (3) write through `logger` (syslog) and let the logging daemon handle rotation. Don't learn this lesson in production — set logrotate `copytruncate` for app logs.

Related commands

Related tasks