1. Overview
When we use ssh to run commands on a remote machine, we may encounter the error message “Pseudo-terminal will not be allocated because stdin is not a terminal”.
In this tutorial, we’ll discuss what this error means, what causes it, and different ways to fix it.
2. What Does the Error Mean?
A pseudo-terminal, pseudo-TTY, or simply pty is a device that emulates a physical terminal. It allows programs to interact with users as if they’re running on a real terminal, even if they’re not.
When we use ssh to connect to a remote machine, ssh allocates a pty on the remote machine and connects it to our local terminal. However, sometimes we may want to run a command on the remote machine without a terminal. For example, we may want to redirect the standard input (stdin) of the command from a file or another command.
In this case, ssh doesn’t allocate a pty on the remote machine, because stdin isn’t a terminal. This causes problems if the command we’re trying to run expects to be run in a terminal. The command may fail or behave unexpectedly, and ssh prints this error message.
3. What Causes the Error?
There are several scenarios that can lead to the “Pseudo-terminal will not be allocated because stdin is not a terminal” error.
One such scenario is when we try to run an interactive command (such as vim or top) on the remote machine without using a terminal:
$ ssh user@host 'vim file.txt'
Another scenario is an attempt to run a command that requires sudo privileges on the remote machine without using a terminal to do so:
$ ssh user@host 'sudo apt update'
In addition, when we try to run a command on the remote machine with stdin redirection from a file or another command, we might see the error:
$ ssh user@host 'cat file.txt' < input.txt
Finally, the issue can also occur if we run the ssh command from a script.
4. How Do We Fix the Error?
There are a variety of ways to fix an error with terminal allocation when using SSH. Let’s explore some of these.
4.1. Forcing Pseudo-TTY Allocation
One way to fix this error is to use the -t option for ssh to force pseudo-TTY allocation. The -t option tells ssh to allocate a pty on the remote machine even if stdin isn’t a terminal. This is useful for running interactive commands or commands that require sudo privileges on the remote machine:
$ ssh -t user@host 'vim file.txt'
Thus, the command above remotely accesses a server through ssh and enables interactive editing of a file using the Vim text editor. We can even run updates like this:
$ ssh -t user@host 'sudo apt update'
This command accesses the remote server and updates the package list on a Ubuntu-based system using the sudo command to gain administrative privileges. In both examples, the -t option forces a terminal to be allocated.
However, sometimes one -t option isn’t enough and we need to use two -t options or -tt for short. The -tt option forces tty allocation even if ssh has no local tty. This is useful for running commands with stdin redirection on the remote machine:
$ ssh -tt user@host 'cat file.txt' < input.txt
Overall, using -t forces a pseudo-TTY allocation and thereby usually resolves the error.
4.2. Disabling Pseudo-TTY Allocation
Another way to fix this error is to use the -T option of ssh to disable pseudo-TTY allocation altogether. The -T option tells ssh not to allocate a pty on the remote machine at all. This is useful for running commands that don’t require a terminal on the remote machine:
$ ssh -T user@host 'ls -l'
This command executes the ls -l command on the remote machine and terminates the connection immediately without allocating a pseudo-TTY.
4.3. Specifying the Shell Explicitly
Another way we can go about working around terminal allocation errors is to specify the shell explicitly for the command on the remote machine. By default, ssh uses the login shell of the remote user to execute commands. However, some shells may not handle stdin redirection well, which results in issues.
By specifying the shell explicitly, we can avoid this problem and run the command in a different shell:
$ ssh user@host '/bin/bash -c "cat file.txt < input.txt"'
This command runs a Bash shell that concatenates the contents of file.txt with input.txt.
5. Conclusion
In this article, we’ve learned what the error “Pseudo-terminal will not be allocated because stdin is not a terminal” means, what causes it, and how we can fix it.
The solutions discussed in this tutorial include forcing pseudo-TTY allocation, disabling pseudo-TTY allocation, and specifying the shell explicitly. By using these solutions, we can execute commands without encountering terminal allocation errors.