How can I run arbitrarily complex command using sudo over ssh?

I have a system that I can only log in to under my username (myuser), but I need to run commands as other user (scriptuser). So far, I have come up with the following to run the commands I need:

ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""

If however, when I try to run a more complex command, such as [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory" I quickly get into trouble with quoting. I'm not sure how I could pass this example complex command to bash -c, when \" already delimites the boundaries of the command I'm passing (and so I don't know how to quote /tmp/Some directory, which includes a spaces.

Is there a general solution allowing me to pass any command no matter how complex/crazy the quoting is, or is this some sort of limitation I have reached? Are there other possible and perhaps more readable solutions?


Solution 1:

A trick I use sometimes is to use base64 to encode the commands, and pipe it to bash on the other site:

MYCOMMAND=$(base64 -w0 script.sh)
ssh user@remotehost "echo $MYCOMMAND | base64 -d | sudo bash"

This will encode the script, with any commas, backslashes, quotes and variables inside a safe string, and send it to the other server. (-w0 is required to disable line wrapping, which happens at column 76 by default). On the other side, $(base64 -d) will decode the script and feed it to bash to be executed.

I never got any problem with it, no matter how complex the script was. Solves the problem with escaping, because you don't need to escape anything. It does not creates a file on the remote host, and you can run vastly complicated scripts with ease.

Solution 2:

See the -tt option? Read the ssh(1) manual.

ssh -tt root@host << EOF
sudo some # sudo shouldn't ask for a password, otherwise, this fails. 
lines
of
code 
but be careful with \$variables
and \$(other) \`stuff\`
exit # <- Important. 
EOF

One thing I often do is use vim and use the :!cat % | ssh -tt somemachine trick.