Bash – “sudo: sorry, you must have a tty to run sudo” when using sudo in a remote script

bashsshsudo

I want to run a series of sudo-elevated commands on a remote machine from an embedded script. To simplify the question, I'm just trying to run sudo id and get it to tell me that it's root.

I am encountering "sudo: sorry, you must have a tty to run sudo" when I run this script:

#!/bin/bash
ssh -t 192.168.1.100<<EOF
sudo id
EOF

But not when I run this:

#!/bin/bash
ssh -t 192.168.1.100 sudo id

How do I get the first one, with the end-of-file designations for an embedded script to respect the forced tty at the other end of the SSH?

Best Answer

With the first one there is no tty for ssh since stdin is not connected to the terminal, it is a here file. In fact if I try to run a similar command (on Debian) I get the following error:

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

To get it to work you can do something like:

ssh -tt 192.168.1.100 <<EOF
sudo -S id
password
EOF

Although this is not a good idea since the password will be in plain text.

Update

I stumbled across an easy solution to this that avoids encoding the password in plain text, you can use a graphical program to enter the password:

ssh -X 192.168.1.100 <<EOF
SUDO_ASKPASS=/usr/lib/ssh/x11-ssh-askpass sudo -A id
EOF

Of course the ssh-askpass program must be installed in the given location and you must be running an X session on the machine you are working on. There are a few variations on the ssh-askpass program which should also work (Gnome/KDE versions). Also a graphical sudo replacement program like gksu or kdesudo should do the job too.

Related Question