11

I'm trying to run a command over SSH like this in a here-document:

ssh example.com <<END
sudo /etc/init.d/apache2 reload
END

Which normally works except when I'm trying to run something that needs input, such as the password for sudo. In that case, I'm getting the following message:

sudo: no tty present and no askpass program specified

I know I can use the -t flag on SSH to allocate a pseudo-tty such as this:

ssh -t example.com "sudo /etc/init.d/apache2 reload"

And it'll work, but when I try the same thing with here-document, it doesn't work and I'll get the same error about no tty being present:

ssh -t example.com <<END
sudo /etc/init.d/apache2 reload
END

Any idea how I can make this work?

Also, in case you are wondering why I want it to work with the here-document instead of just passing it on the same line, it is because the input commands (there can be a few) come from a configuration file read by a script and I've heard it avoids the trouble of escaping the commands for the quotes, double quotes, etc.

2 Answers 2

9

Use visudo to edit the sudoers file and insert a below line:

Defaults:<user>    !requiretty

It doesn't answer why using the ssh -t "something" versus ssh -t <<STOP something STOP doesn't work. Let's say I'm not using sudo but I'm using passwd for my own user directly, I still won't get the TTY using the heredoc.

Try ssh -t -t to force pseudo-tty allocation even if stdin is not a terminal.

2
  • Thanks, I've seen this fix elsewhere, but it only goes around the problem for the commands that use sudo. It doesn't answer why using the ssh -t "something" versus ssh -t <<STOP something STOP doesn't work. Let's say I'm not using sudo but I'm using passwd for my own user directly, I still won't get the TTY using the heredoc.
    – lpfavreau
    Sep 24, 2011 at 17:57
  • I've updated my answer.
    – quanta
    Sep 25, 2011 at 4:06
2

Why not simply store the here document in a variable that will be given ssh -t as a command argument.

On a more general note, use ssh -T or specify the remote shell as a command argument if the stdin of the remote host is being redirected from a heredoc (to prevent ssh from trying to allocate a pty).

# store heredoc in a variable
heredoc="$(cat <<EOF
who
sudo ls -ld /
logname
EOF
)"

ssh -t localhost "$heredoc"


# avoid: Pseudo-terminal will not be allocated because stdin is not a terminal.
- ssh example.com <<END
+ ssh -T example.com <<END
+ ssh example.com /bin/sh <<END

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .