Matt Brown
06/11/2026, 3:08 AMcommands:
name: ssh
steps:
- type: shell
output: raw
command: "exec aws ssm start-session --target {{ .Arguments.instance_id }}"
but the exec seems to be within a subprocess itself, so doesn't replace atmos and the terminal gets all bunged up, most obviously if you try and Ctrl-C a command in the session, atmos itself takes teh Ctrl-C exits, and then the session ends with SIGPIPE š
Feels like a common need I would have thought, but I'm failing to find the right invocation in the docs...Erik Osterman (Cloud Posse)
06/11/2026, 3:46 PMErik Osterman (Cloud Posse)
06/11/2026, 3:46 PMtty
⢠interactiveErik Osterman (Cloud Posse)
06/11/2026, 3:47 PMErik Osterman (Cloud Posse)
06/11/2026, 5:08 PMatmos --use-version=2602 ...
https://github.com/cloudposse/atmos/pull/2602Matt Brown
06/11/2026, 8:02 PMMatt Brown
06/11/2026, 10:33 PMmatt@argon:~/mkmba/cloud-infra$ atmos --use-version=2602 ssh --identity dev-ocopt i-0a...
ā PR #2602 is up to date (sha: 8fd822b)
ā Switching to Atmos version 2602
Starting session with SessionId: matt@...
sh-5.2$ ^C
sh-5.2$
exit
Exiting session with sessionId: matt@...
matt@argon:~/mkmba/cloud-infra$
/home/matt/mkmba/cloud-infra
(I hit Ctrl-C again after the "exiting session with.." text to get back to the prompt; and then typed 'pwd' which wasn't echoed.Erik Osterman (Cloud Posse)
06/11/2026, 10:48 PMErik Osterman (Cloud Posse)
06/11/2026, 11:21 PMErik Osterman (Cloud Posse)
06/11/2026, 11:21 PMMatt Brown
06/12/2026, 2:29 AMErik Osterman (Cloud Posse)
06/12/2026, 4:11 AMMatt Brown
06/12/2026, 4:12 AMErik Osterman (Cloud Posse)
06/14/2026, 5:12 AMErik Osterman (Cloud Posse)
06/15/2026, 8:04 PMMatt Brown
06/15/2026, 8:06 PMMatt Brown
06/15/2026, 9:30 PMmatt@argon:~/mkmba/cloud-infra$ atmos --use-version 2602 ssh --identity dev-ocopt i-0d315f6f53616a157
ā PR #2602 is up to date (sha: 887a988)
ā Switching to Atmos version 2602
Starting session with SessionId: <mailto:matt@mkmba.nz|matt@mkmba.nz>-jreklqgdksy3jc7v9txls74g6a
sh-5.2$ matt@argon:~/mkmba/cloud-infra$
aws: [ERROR]: Command '['session-manager-plugin', 'AWS_SSM_START_SESSION_RESPONSE', 'ap-southeast-2', 'StartSession', '', '{"Target": "i-0d315f6f53616a157"}', '<https://ssm.ap-southeast-2.amazonaws.com>']' died with <Signals.SIGPIPE: 13>.Erik Osterman (Cloud Posse)
06/15/2026, 9:41 PMbase_path: "."
logs:
level: Info
commands:
# 1. Basic terminal session (the SSM stand-in).
# Expect: a bash prompt; full-screen apps render; exit/Ctrl-D returns you
# to your own shell immediately with echo working.
- name: test-tty
description: Interactive bash in a tty step (SSM session stand-in)
steps:
- type: shell
tty: true
interactive: true
command: "bash --norc -i"
# 2. Matt's repro - grandchild keeps the PTY open after the session exits
# (this is what aws ssm's session-manager-plugin does).
# Expect WITH the fix: after `exit`, your prompt is back within ~1 second
# and echo works. WITHOUT the fix: hang until a keypress, then no echo.
- name: test-lingering
description: Reproduce the SSM teardown hang (background child holds the PTY)
steps:
- type: shell
tty: true
interactive: true
command: "sleep 60 & bash --norc -i"
# 3. Ctrl-C handling - press Ctrl-C while sleep runs.
# Expect: the sleep is interrupted (atmos exits 130 from the step), your
# terminal is sane afterwards. Atmos itself was NOT killed by the signal -
# it returned through normal teardown (terminal restored, exit code clean).
- name: test-ctrlc
description: Ctrl-C goes to the step, not atmos
steps:
- type: shell
tty: true
interactive: true
command: "echo 'Press Ctrl-C now...'; sleep 30; echo 'not interrupted'"
# 4. Interactive without tty - prompts work, output still masked/managed.
- name: test-interactive
description: Interactive (non-tty) step reads stdin
steps:
- type: shell
interactive: true
command: "printf 'type something: '; read x; echo \"you typed: $x\""
# 5. exec step - replaces the atmos process entirely.
# Expect: `ps -o ppid= -p $$` inside the shell shows your TERMINAL's shell
# as parent (no atmos in the process tree - it was replaced). Ctrl-Z job
# control is native. Exit code propagates: run `exit 7`, then `echo $?`
# in your own shell shows 7.
- name: test-exec
description: Replace the atmos process (shell exec semantics)
steps:
- type: exec
command: "bash --norc -i"
# 6. Validation - exec must be the final step.
# Expect: immediate error, nothing executes.
- name: test-exec-invalid
description: Exec step not last - must fail validation
steps:
- type: exec
command: "echo never runs"
- type: shell
command: "echo unreachable"
# 7. Plain step - unchanged behavior (baseline).
- name: test-plain
description: Plain shell step (baseline, unchanged behavior)
steps:
- "echo plain step ok"
# 8. Color self-test (non-interactive). tty:true allocates a PTY so the
# program sees a real terminal; color should render. Exits on its own.
- name: test-color
description: Print a color self-test inside a tty step
steps:
- type: shell
tty: true
command: |
echo "TERM=$TERM"
echo "tput colors: $(tput colors 2>/dev/null)"
printf '\033[31mRED\033[0m \033[32mGREEN\033[0m \033[33mYELLOW\033[0m \033[34mBLUE\033[0m\n'
printf '\033[1mBOLD\033[0m \033[4mUNDERLINE\033[0m \033[7mINVERSE\033[0m\n'
command -v tput >/dev/null && tput setaf 1 && echo "tput red" && tput sgr0
# 9. Color in an interactive session: drops you into bash to type your own
# color checks (see README).
- name: test-color-interactive
description: Interactive bash to test color by hand
steps:
- type: shell
tty: true
interactive: true
command: 'echo "TERM=$TERM, colors=$(tput colors 2>/dev/null)"; exec bash --norc -i'Erik Osterman (Cloud Posse)
06/15/2026, 9:41 PMatmos --chdir=/tmp/atmos-tty-test test-lingeringErik Osterman (Cloud Posse)
06/15/2026, 9:42 PM^C it goes to the shell and does not kill Atmos.Erik Osterman (Cloud Posse)
06/15/2026, 9:42 PMErik Osterman (Cloud Posse)
06/15/2026, 9:42 PMMatt Brown
06/15/2026, 9:55 PMMatt Brown
06/15/2026, 9:56 PMMatt Brown
06/15/2026, 9:56 PMMatt Brown
06/15/2026, 10:09 PMErik Osterman (Cloud Posse)
06/15/2026, 10:10 PMMatt Brown
06/15/2026, 10:11 PMMatt Brown
06/15/2026, 10:12 PMErik Osterman (Cloud Posse)
06/15/2026, 10:12 PMErik Osterman (Cloud Posse)
06/15/2026, 10:12 PM