I am trying to remotely run a shell script on an ubuntu host.
I can ssh to the machine using me@host just fine.
On the remote machine I can run sudo commands without needing to input a password.
I can run a shell command on the remote host just fine using rsh
So now I put a sudo command and I get an error
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helperthe command I run is the following:
ssh user@hostIPAddress "cd /opt/somewhere && sh -v -v ./install.sh"the install.sh contains one command that requires a sudo command
#!/bin/bash
sudo pm2 stop someprocessHow do I get around this error?
142 Answers
If you don't want sudo to prompt for a password, after understanding the security implications, you can edit the sudoers file. However, it is not safe to edit the file directly. Instead, use:
sudo visudoTo allow running your specific program without a password, add a line to sudoers in the format:
YOURNAME ALL = NOPASSWD: /path/to/pm2 stop someprocessAbove, replace YOURNAME with your login on that system, and /path/to/pm2 with the full path to that program (output of which pm2).
If you want to allow running pm2 passwordless with any parameters, not just stop someprocess, then delete those last 2 words from the line.
For more on editing sudoers, see How to run an application using sudo without a password and man sudoers and man visudo.
Changing the behavior of ssh
When you run ssh without a command and there is a local pseudo-terminal, the tool allocates a pseudo-terminal on the remote side automatically. Usually you access an interactive remote shell this way, so allocating a terminal is the right thing to do.
When you provide a remote command to ssh, it assumes the command is not interactive. It doesn't provide a pseudo-terminal to the command. This happens in your case, sudo finds no terminal.
You can explicitly tell local ssh to allocate a pseudo-terminal on the remote side:
-t
Force pseudo-terminal 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-toptions force tty allocation, even ifsshhas no local tty.
(source)
ssh -t user@hostIPAddress "cd /opt/somewhere && sh -v -v ./install.sh"Note when you do this, you can no longer tell the stdout and stderr of ./install.sh apart locally. Read the "broader picture" part of this another answer of mine.
Changing the behavior of sudo
sudo suggests alternative solutions that depend solely on sudo itself:
sudo: a terminal is required to read the password; either use the-Soption to read from standard input or configure an askpass helper
These are:
- read from standard input:
sudo -S(see this answer); - configure an askpass helper:
sudo -A(see the second part of this answer).
Both require an argument to sudo, so you would need to change the script. It's easy to lessen security by using any of these options. Strongly prefer ssh -t. Note in general sudo may be configured not to work without a terminal anyway.