ssh user@host "command": Run a Remote Command
ssh user@host "command" executes the command on the server, prints its output, and exits with the command's status.
This is the core of any SSH deploy: connect, run the deploy script, and let the remote exit code pass or fail the job. A few quoting and TTY details keep it reliable.
What it does
When you append a command, ssh runs it through the remote login shell instead of opening an interactive session, then exits with the remote command's exit code. Stdout and stderr stream back to the runner so the job log captures them.
Common usage
ssh user@host "cd /srv/app && git pull && systemctl --user restart app"
# multi-line script via a heredoc
ssh user@host 'bash -s' <<'EOF'
set -euo pipefail
cd /srv/app
docker compose pull
docker compose up -d
EOFOptions
| Form | What it does |
|---|---|
| ssh host "cmd" | Run cmd remotely; exit with its status |
| ssh host 'bash -s' < script | Pipe a local script to a remote shell |
| -t | Force a pseudo-terminal (for interactive remote tools) |
| -T | Disable pseudo-terminal allocation |
In CI
Quote the whole command so local and remote shells expand variables where you intend. Start remote scripts with set -euo pipefail so a failing step propagates a non-zero exit back to the runner. The remote exit code is what passes or fails the CI step.
Common errors in CI
Pseudo-terminal will not be allocated because stdin is not a terminal. is a harmless warning when -t is used without a TTY; drop -t or add -T. "bash: deploy.sh: command not found" means the remote PATH or working directory differs from an interactive login; use an absolute path or cd first. A non-zero exit from the remote command fails the step by design.