Pseudo-terminal will not be allocated because stdin is not a terminal Pseudo-terminal will not be allocated because stdin is not a terminal linux linux

Pseudo-terminal will not be allocated because stdin is not a terminal


Try ssh -t -t(or ssh -tt for short) to force pseudo-tty allocation even if stdin isn't a terminal.

See also: Terminating SSH session executed by bash script

From ssh manpage:

-T      Disable pseudo-tty allocation.-t      Force pseudo-tty allocation.  This can be used to execute arbitrary         screen-based programs on a remote machine, which can be very useful,        e.g. when implementing menu services.  Multiple -t options force tty        allocation, even if ssh has no local tty.


Also with option -T from manual

Disable pseudo-tty allocation


Per zanco's answer, you're not providing a remote command to ssh, given how the shell parses the command line. To solve this problem, change the syntax of your ssh command invocation so that the remote command is comprised of a syntactically correct, multi-line string.

There are a variety of syntaxes that can be used. For example, since commands can be piped into bash and sh, and probably other shells too, the simplest solution is to just combine ssh shell invocation with heredocs:

ssh user@server /bin/bash <<'EOT'echo "These commands will be run on: $( uname -a )"echo "They are executed by: $( whoami )"EOT

Note that executing the above without /bin/bash will result in the warning Pseudo-terminal will not be allocated because stdin is not a terminal. Also note that EOT is surrounded by single-quotes, so that bash recognizes the heredoc as a nowdoc, turning off local variable interpolation so that the command text will be passed as-is to ssh.

If you are a fan of pipes, you can rewrite the above as follows:

cat <<'EOT' | ssh user@server /bin/bashecho "These commands will be run on: $( uname -a )"echo "They are executed by: $( whoami )"EOT

The same caveat about /bin/bash applies to the above.

Another valid approach is to pass the multi-line remote command as a single string, using multiple layers of bash variable interpolation as follows:

ssh user@server "$( cat <<'EOT'echo "These commands will be run on: $( uname -a )"echo "They are executed by: $( whoami )"EOT)"

The solution above fixes this problem in the following manner:

  1. ssh user@server is parsed by bash, and is interpreted to be the ssh command, followed by an argument user@server to be passed to the ssh command

  2. " begins an interpolated string, which when completed, will comprise an argument to be passed to the ssh command, which in this case will be interpreted by ssh to be the remote command to execute as user@server

  3. $( begins a command to be executed, with the output being captured by the surrounding interpolated string

  4. cat is a command to output the contents of whatever file follows. The output of cat will be passed back into the capturing interpolated string

  5. << begins a bash heredoc

  6. 'EOT' specifies that the name of the heredoc is EOT. The single quotes ' surrounding EOT specifies that the heredoc should be parsed as a nowdoc, which is a special form of heredoc in which the contents do not get interpolated by bash, but rather passed on in literal format

  7. Any content that is encountered between <<'EOT' and <newline>EOT<newline> will be appended to the nowdoc output

  8. EOT terminates the nowdoc, resulting in a nowdoc temporary file being created and passed back to the calling cat command. cat outputs the nowdoc and passes the output back to the capturing interpolated string

  9. ) concludes the command to be executed

  10. " concludes the capturing interpolated string. The contents of the interpolated string will be passed back to ssh as a single command line argument, which ssh will interpret as the remote command to execute as user@server

If you need to avoid using external tools like cat, and don't mind having two statements instead of one, use the read built-in with a heredoc to generate the SSH command:

IFS='' read -r -d '' SSH_COMMAND <<'EOT'echo "These commands will be run on: $( uname -a )"echo "They are executed by: $( whoami )"EOTssh user@server "${SSH_COMMAND}"