"Killed" message in Bash

A bash process printing just "Killed" usually means the OOM killer or a manual SIGKILL terminated it. Check `dmesg` and memory limits.

Error String

Killed

Tldr

When a bash process is terminated by SIGKILL, the parent shell prints "Killed" with no other context. The two common causes are the Linux OOM killer (the process used too much memory) and a deliberate `kill -9` from another process or container orchestrator.

Cause

SIGKILL cannot be trapped, so the script has no chance to print a useful error. Check `dmesg | tail` for "Out of memory: Killed process" lines. In containers, check the platform's OOMKilled flag and cgroup memory limit.

Repro

# Allocate 8 GiB on a 4 GiB system:
yes | head -c 8G > /dev/null     # may be Killed by OOM

Fix

# 1. Investigate:
dmesg | tail -50
journalctl -k | grep -i oom

# 2. Reduce memory or stream instead of buffering:
process_large_file < input.txt   # don't pre-load with $(cat)

# 3. Raise the cgroup/container limit if the workload is legitimate.

Explanation

Most Bash "Killed" surprises in pipelines come from a child process (awk, sort, jq) loading everything into memory. Stream where possible (sort -m, awk '$1>10') and tune memory only when the workload truly needs it.

Faq

Q

Why did my EXIT trap not run?

A

SIGKILL terminates the process immediately; the shell never regains control to run traps.

Q

What is the difference between 137 and 143?

A

137 is SIGKILL (9), 143 is SIGTERM (15). SIGTERM is trappable, so a graceful shutdown handler can run.

Deep Dive

Heading

SIGKILL cannot be trapped

Body

Exit status 137 is 128 + 9: the process received SIGKILL. Nothing in the script can catch it, so no trap runs and no cleanup happens. The sender is usually the Linux OOM killer, a container runtime enforcing a memory limit, a CI job timeout, or an operator running `kill -9`. Check `dmesg -T | grep -i oom` or `journalctl -k` for an OOM record naming your process, and in Kubernetes look for `OOMKilled` in the pod status.

Heading

Reducing memory pressure in shell pipelines

Body

Shell scripts hit memory limits when they slurp whole files into variables, build enormous argument lists, or sort giant inputs. Stream instead: read line by line with `while IFS= read -r line`, pass `sort -S` a bounded buffer, and use `xargs` with `-n` so argument lists stay small. If the work is legitimately large, raise the container memory limit rather than hoping the shell uses less; because SIGKILL is untrappable, the only reliable safeguard is a wrapper that notices the 137 status and retries or reports it.

Checklist

Look for an OOM record in `dmesg -T` or the container events.

Check the runtime memory limit against actual peak usage.

Stream large inputs instead of loading them into variables.

Handle status 137 in the caller — the script itself cannot.