I can log in to a remote machine as a user who can do sudo su -. I can't login as root.

I have a script locally that I want to run at the remote machine. Also, the script is sent there trough another script.

I can't figure out how. I've red quite a few Q&A's here but no success. The closest I have:

COMMAND_SSH="sudo -i <<\'EOF\'"`cat ./unifyServiceNode.sh`"\\nEOF\\n" ;;
while read HOST; do
  echo -e "\n\n======== $USER_@$HOST <-- $COMMAND_SSH =================\n\n";
  ssh -n -tt centos@$HOST "'$COMMAND_SSH'";
done < hosts.txt

This ends up with this output:

======== [email protected] <-- sudo -i <<\'EOF\'
##  Creates a few links and scripts to unify the nodes maintainance.


  mkdir -p $BB
  ln -s /opt/$NAME/logs/*.log $BB/log
  ln -s /opt/$NAME/conf/api/$NAME.yml $BB/conf.yml || ln -s /opt/$NAME/conf/api/$NAME2.yml $BB/conf.yml
  echo "systemctl \${1:-restart} "${@:2}" $NAME" > $BB/Sys
  echo "tail -\${1:-500f} $BB/log" > $BB/Tail
  echo "nano $BB/conf.yml" > $BB/Conf
  chmod a+x $BB/Sys $BB/Tail $BB/Conf
  echo "export PATH=\$PATH:$BB" >> ~/.bashrc

bash: sudo -i <<\EOF': command not found
bash: line 14: /bb/Sys: Permission denied
bash: line 15: /bb/Tail: Permission denied
bash: line 16: /bb/Conf: Permission denied
chmod: changing permissions of ‘/bb/Sys’: Operation not permitted
chmod: changing permissions of ‘/bb/Tail’: Operation not permitted
chmod: changing permissions of ‘/bb/Conf’: Operation not permitted
bash: -c: line 18: unexpected EOF while looking for matching `''
bash: -c: line 19: syntax error: unexpected end of file
Connection to somehost.com closed.

This is the "closest" because it sees the individual commands but is not under sudo, because the first line's <<EOF isn't (un)escaped properly.

**How should I execute an arbitrary script under sudo over ssh?"

  • 1
    Why do you want to put a command in a variable?
    – Kusalananda
    Mar 2, 2018 at 6:54

4 Answers 4


I have figured out soon after posting.

COMMAND_SSH="sudo -i <<'EOF'"`cat ./unifyServiceNode.sh``echo -e '\nEOF'` ;;

ssh -n -tt centos@$HOST "$COMMAND_SSH"; ## -n prevents reading the input. -tt forces TTY.

The extra 's around the SSH command were the issue it seems, and I also needed to make the newline through echo.

I am not quite sure if that's just a lucky hack or the right way to do it, though. To be honest, I am completely lost in Bash's quotes evaluation :)


Your current method is very convoluted, which is what's making it difficult to work with.
This can instead be simplified to:

ssh -i $AWS_KEY centos@$HOST sudo sh < ./unifyServiceNode.sh
  • Doesn't work in my case. For ssh to run sudo, it needs -tt, otherwise I get sudo: sorry, you must have a tty to run sudo. And if I use -tt, then < redirection is ignored. Apr 27, 2018 at 21:57
  • you can overcome the requirement for TTY by setting in the sudoers file: requiretty=off. If set, sudo will only run when the user is logged in to a real tty. When this flag is set, sudo can only be run from a login session and not via other means such as cron(8) or cgi-bin scripts. This flag is off by default. Apr 5, 2019 at 10:24

Put the commands that you need to execute in a script, transfer that script over to the host using scp and run it through ssh.

Or, feed the here-document to the appropriate shell:

ssh server sh <<'END_SCRIPT'
script code
goes here

Or, use Ansible or similar system which is made for remote configuration of multiple hosts.

You generally do not want to put commands in variables.

  • Sure, but I wanted to do this in one step. Ideal would be some kind of scpAndRun command. Apr 27, 2018 at 21:58
  • Regarding commands in variables - I have a 2 pass script that creates the command in one part, and the way to execute it on remote servers is in other part. Is there other mechanism for that than a variable which I could use in one step with ssh? Apr 27, 2018 at 22:02

If you're willing to store plain text passwords (obviously a bad idea), you can combine sshpass -p "my_ssh_password", ssh << HEREDOC and echo "my_sudo_password" | sudo -S my_cmd to do it.


sshpass -p "my_ssh_password" ssh my_user@my_ip << 'ENDSSH'
echo "my_sudo_password" | sudo -S my_sudo_command1
echo "my_sudo_password" | sudo -S my_sudo_command2
echo "my_sudo_password" | sudo -S my_sudo_script

You must log in to answer this question.

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