SSH server will not include the command prompt if no PTY is requested
This is one of the most important behaviors to understand when automating SSH, and it is exactly why avoiding a PTY is highly recommended for scripting.
Here is why the prompt disappears and how it works behind the scenes:
1. The isatty() Check and Non-Interactive Mode
When a shell program (like Bash, Zsh, or sh) starts on the remote server, it immediately checks if its standard input is connected to a terminal device. It does this using a system call like isatty().
- With a PTY: The shell sees it is connected to a terminal. It enters interactive mode, meaning it prints the Message of the Day (MOTD), executes
.bashrc, echoes everything you type, and constantly prints the command prompt ($PS1, e.g.,user@host:~$) to tell the human user it is ready for input. - Without a PTY: The shell realizes it is just connected to a raw data pipe. It enters non-interactive mode. In this mode, the shell assumes it is talking to a script or a program, not a human. Therefore, it completely suppresses the command prompt, it does not echo your typed commands back to you, and it skips interactive login scripts.
2. How this affects the two ways you execute commands:
Sending an exec request (Single Command):
If your SSH client opens a channel and sends an exec request (e.g., executing ls -l), the SSH server passes this to the shell using a flag like bash -c "ls -l". The shell runs the command, returns exactly the standard output (and standard error), and immediately exits. There is never a prompt.
Sending a shell request (Multiple Commands):
If you open a shell channel without requesting a PTY, you can stream multiple commands into the session one after the other.
Because it is in non-interactive mode, you will essentially be interacting with it like a raw pipe. You send a command (followed by a newline), and the server will return only the output of that command. You will not see a prompt before or after the output.
Summary for Automation
If you are writing software to interact with an SSH server:
- No PTY = Clean Output: You get pure, easily parseable
stdoutandstderrdata. No prompts, no ANSI color codes, and no echoed input. - The Catch: Because there is no prompt, your software cannot rely on searching for
user@host:~$to know when a command has finished executing. Instead, you must rely on the SSH protocol itself (waiting for the channel to send anEOFor an exit status), or structure your commands so they output a specific, predictable string when they are done.