| Tested on | Red Hat Enterprise Linux 10.2 (Coughlan) |
|---|---|
| Package | podman-5.8.2-5.el10_2.x86_64 |
| Applies to | Any Linux host with Podman installed |
| Privilege | Rootful examples on the lab host; flags behave the same rootless unless noted |
| Scope | podman exec on running containers — syntax, one-off commands, -it shells, --user, -w, --env, --env-file, -d, flag ordering, exit codes, and a short exec vs attach comparison. Does not cover podman run, lifecycle commands, SSH server setup, user-namespace mappings, or full attach reference. |
| Related guides | List containers with podman ps Install Podman on RHEL What is Podman? |
podman exec runs a command inside a container that is already running. Container creation belongs in Run containers with podman run; this page reuses one long-running container named exec-demo for every example.
Podman exec syntax
The general form is:
podman exec [options] CONTAINER COMMAND [arguments...]Option order matters. Think of it as two layers:
podman exec [PODMAN EXEC OPTIONS] CONTAINER COMMAND [COMMAND OPTIONS]Everything before CONTAINER is interpreted by Podman. Everything after is the program to run inside the container namespace.
Create the demo container:
podman run -d --name exec-demo registry.access.redhat.com/ubi9/ubi-minimal sleep 3600Confirm it is running before any exec:
podman ps --filter name=exec-demoSample output:
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
9e4c96730863 registry.access.redhat.com/ubi9/ubi-minimal:latest sleep 3600 2 seconds ago Up 1 second exec-demoRun a command inside a running container
Start with a read-only inspection command:
podman exec exec-demo cat /etc/os-releaseSample output:
NAME="Red Hat Enterprise Linux"
VERSION="9.8 (Plow)"
ID="rhel"
PRETTY_NAME="Red Hat Enterprise Linux 9.8 (Plow)"podman exec starts another process in the existing container namespace. It does not create a second container, and the main process (sleep 3600 here) keeps running. When the exec command exits, the container normally stays up unless you exec'd into PID 1 or otherwise changed container state.
Open an interactive shell with podman exec -it
Interactive shells need STDIN kept open and a pseudo-TTY:
-i— keep STDIN open for typed or piped input-t— allocate a terminal
On exec-demo (UBI 9 minimal), Bash is available:
podman exec -it exec-demo /bin/bashYour prompt moves inside the container until you type exit or press Ctrl+D.
Many minimal images ship only sh. Create a short-lived Alpine container to show the Bash mistake:
podman run -d --name exec-alpine docker.io/library/alpine:3.20 sleep 3600Request Bash on an image that only ships sh:
podman exec exec-alpine /bin/bashSample output on Alpine 3.20:
Error: crun: executable file `/bin/bash` not found: No such file or directory: OCI runtime attempted to invoke a command that was not foundUse the shell the image actually provides:
podman exec -it exec-alpine /bin/shInspect the image (podman inspect or the image Dockerfile) instead of installing SSH just to obtain a shell.
Put podman exec options before the container name
Flags must come before the container name. Correct form:
podman exec -it exec-demo /bin/shSwapping the order fails:
podman exec exec-demo -it /bin/shSample output on Podman 5.8.2:
Error: crun: executable file `-it` not found in $PATH: No such file or directory: OCI runtime attempted to invoke a command that was not foundAfter Podman reads exec-demo, the next token is the command. -it is not a valid program name inside the container, so crun reports executable file not found. The same mistake with mistyped flags produces similar errors — always place Podman options first.
Run a command as another user
Without --user, exec runs as the container's configured user (root by default on many images):
podman exec exec-demo idSample output:
uid=0(root) gid=0(root) groups=0(root)Run as a specific account by name or numeric UID:
podman exec --user 1000 exec-demo idSample output:
uid=1000 gid=0(root) groups=0(root)The UID inside the container is not necessarily the same UID on the host when user namespaces are enabled. Mapping details live in Podman user namespaces — this page only shows the exec flag.
Set the working directory with -w
-w sets the working directory for the exec process only:
podman exec -w /tmp exec-demo pwdSample output:
/tmpIt does not change the container's permanent configuration. A path that does not exist fails:
podman exec -w /no/such/dir exec-demo pwdSample output:
Error: crun: chdir to `/no/such/dir`: No such file or directoryThe command itself may exist; this failure occurs because crun cannot change into the requested working directory before starting it. Create the directory inside the container first, or pick a path that already exists.
Pass environment variables to podman exec
Add variables for a single exec session with --env:
podman exec --env DEMO=value exec-demo printenv DEMOSample output:
valueFor several variables, write a host file first:
printf "DEMO_FILE=from-file\n" > /tmp/exec-env.txtPass that file into one exec session:
podman exec --env-file /tmp/exec-env.txt exec-demo printenv DEMO_FILEThose variables apply to the exec process only. They do not rewrite the container's stored environment the way podman run -e does at create time.
Run a command in the background
-d starts the exec process detached and prints an exec session ID:
podman exec -d exec-demo sh -c "echo detached-exec > /tmp/exec-test.txt"Sample output:
ed134f4557e3645177c768b3ee920b8b799c1ebff72ad64b3c32f87cf49afabcVerify the command ran inside the container:
podman exec exec-demo cat /tmp/exec-test.txtSample output:
detached-execDo not confuse podman run -d with podman exec -d. run -d creates and starts a new container in the background. exec -d adds another process inside a container that is already running.
What happens if the container is stopped?
podman exec requires a running container. Stop exec-demo first:
podman stop exec-demoThen exec fails because nothing is running:
podman exec exec-demo /bin/sh -c "echo hi"Sample output:
Error: can only create exec sessions on running containers: container state improperStart the container, then the same exec succeeds:
podman start exec-demoRetry the command:
podman exec exec-demo /bin/sh -c "echo after-start"Sample output:
after-startLifecycle commands that change running state are covered in Start, stop, and restart containers.
Understand podman exec exit codes
Podman follows Docker-style exit conventions for exec:
| Exit code | Meaning |
|---|---|
| 125 | Podman itself failed, such as invalid options or another Podman-level error |
| 126 | Command was found but cannot be invoked |
| 127 | Command was not found |
| Other | Exit status returned by the executed command |
Command not found inside the container:
podman exec exec-demo command-that-does-not-existCheck the shell exit status:
echo $?Sample output:
127Non-zero exit from the command itself is passed through:
podman exec exec-demo sh -c "exit 3"Podman returns the command's exit code:
echo $?Sample output:
3Exit 126 appears when the target exists but cannot execute — for example a directory path:
podman exec exec-demo /etcThat yields 126:
echo $?Sample output:
126Podman-level failures use 125, such as a missing container name:
podman exec no-such-container idMissing containers surface as 125:
echo $?Sample output:
125podman exec vs podman attach
podman exec |
podman attach |
|---|---|
| Starts a new process in the running container | Connects to the existing main process |
You supply the command (/bin/sh, cat, etc.) |
No new command — attaches to PID 1's I/O |
Can set --user, -w, and --env per exec |
Uses the running process context |
| Common for shells and one-off admin tasks | Common for foreground apps started with run |
podman attach supports detach keys (default Ctrl+P, Ctrl+Q) so you can leave the main process running without stopping it. Use exec when you need a separate command; use attach when you need the original foreground session.
Do you need SSH inside a Podman container?
Most images do not run sshd. For administration on the host where Podman runs, podman exec is the direct path to a shell or diagnostic command — no SSH hop required.
When you need to move files in or out without opening a shell, copy files with podman cp works on stopped containers too — unlike exec.
SSH inside a container can still be valid for specially designed images or remote-access patterns. This article stays on podman exec as the default local mechanism.
References
Summary
podman exec runs additional processes inside a container that is already running. The main workload keeps going while you inspect files, open a shell, or run a one-off command. Place every Podman flag before the container name — putting -it after the name makes Podman try to execute a program literally named -it, which is a common copy-paste mistake with a clear error on Podman 5.8.2.
Use -it for interactive shells, but match the shell the image provides (/bin/sh on Alpine, /bin/bash on UBI). --user, -w, and --env apply only to the exec session. -d runs exec in the background and returns a session ID. Exec fails when the container is stopped; start it first. Exit codes 125, 126, and 127 distinguish Podman errors, non-executable targets, and missing commands — check echo $? in scripts that branch on failure.
For foreground workloads you started with podman run, podman attach reconnects to PID 1 instead of launching a new process. For everything else on a running container, exec is the tool you reach for — not SSH, unless the image was built for that on purpose.

