Most SSH connections start with a hostname and a username. The options come in when you need a different port, a particular key, or enough diagnostic output to figure out why a connection failed.
Here are the command patterns worth knowing—and how to avoid a few common surprises.
Start with the destination
The general OpenSSH syntax is:
ssh [options] [user@]hostname [remote-command]
For an interactive shell, provide a user and host:
ssh sam@example.com
If you leave out the username, SSH uses your current local username as the remote username. You can also write the username with -l:
ssh -l sam example.com
On a first connection, SSH may show the server’s host key fingerprint and ask you to confirm it. Don’t treat a changed fingerprint on a familiar host as a routine prompt: verify the change through a trusted channel before accepting it.
Add options when the connection needs them
Options that take values should be followed by those values. For example, -p selects a port and -i selects a private key:
ssh -p 2222 sam@example.com
ssh -i ~/.ssh/id_ed25519 sam@example.com
SSH normally connects over TCP port 22. Use -p when the server listens on a different port; the port is an argument to the option, not part of the hostname.
Use -i when you need to select a key explicitly—for example, if you have multiple identities or the key doesn’t use a default filename that SSH checks automatically. Keep private keys private; the file named here is not the public key you upload to a server.
For a longer walkthrough of choosing and using a particular identity file, see how to connect with an SSH private key.
Run a command without opening a shell
Put a command after the destination to run it remotely:
ssh sam@example.com uptime
SSH connects, runs uptime on the remote machine, and returns the command’s output. This is handy for one-off checks and scripts where an interactive shell would be unnecessary.
For commands that need interaction—such as a program that expects a terminal—SSH has the -t option to force pseudo-terminal allocation:
ssh -t sam@example.com 'sudo systemctl restart nginx'
You won’t need -t for every remote command. Use it when the remote program needs a terminal, such as for an interactive prompt.
Debug a connection in stages
When a connection fails, -v prints details about what the client is doing:
ssh -v sam@example.com
Start with one -v. It can show which keys SSH offers, which authentication methods the server accepts, and where the connection gets stuck. Repeat the option for more output:
ssh -vv sam@example.com
ssh -vvv sam@example.com
The extra detail can help when the initial output isn’t enough, but it can also be noisy. If you need help interpreting the messages, this SSH verbose-mode guide explains what to look for.
Stop retyping the same options
If you connect to the same host repeatedly, put its settings in ~/.ssh/config instead of memorizing a long command. For example:
Host staging
HostName staging.example.com
User sam
Port 2222
IdentityFile ~/.ssh/id_ed25519
Then connect using the alias:
ssh staging
Command-line options can override corresponding settings from SSH configuration for that invocation. That makes a one-time change easy without editing your file:
ssh -p 2200 staging
Within configuration files, SSH uses the first value it finds for an individual setting. Put specific host entries before broad defaults such as Host *; otherwise, an earlier matching setting may take precedence over the one you intended.
A quick reference
| Need | Command pattern |
|---|---|
| Connect to a host | ssh user@host |
| Use a custom port | ssh -p 2222 user@host |
| Select a private key | ssh -i ~/.ssh/keyfile user@host |
| Run a remote command | ssh user@host uptime |
| See connection diagnostics | ssh -v user@host |
| Use a host alias | ssh alias |
Most of the time, the destination is all you need. Add flags for a specific connection requirement, and move settings you reuse into your SSH config.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.
Top comments (0)