Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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?

share|improve this question
3  
Copy a script to $remote then execute it. –  Iain yesterday
    
That would work, but I find a solution which leaves no script files behind (in case something fails etc.) would be a bit cleaner. –  VoY yesterday
3  
have the script rm itself at end of each run –  thanasisk yesterday
1  
Consider to use fabric fabfile.org. Can make you life much easier if you have to sudo remotely a lot. –  Nils Toedtmann yesterday
    
Can we assume you've set up sudo so that it does not require a pasword prompt? –  Mike yesterday

5 Answers 5

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

MYCOMMAND=`base64 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. 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.

share|improve this answer
3  
You can base64 script.sh to avoid a UUOC –  l0b0 yesterday
1  
Thanks! I used to point it to other users and ended up doing the same. Fixed. –  ThoriumBR yesterday

Simply,

ssh root@host << EOF
some
lines
of
code 
but be careful with \$variables
and \$(other) \`stuff\`
EOF

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

share|improve this answer

I think the easiest solution lies in a modification of @thanasisk's comment.

Create a script, scp it to the machine, then run it.

Have the script rm itself at the start. The shell has opened the file, so it's been loaded, and can then be removed without problems.

By doing things in this order (rm first, other stuff second) it'll even be removed when it fails at some point.

share|improve this answer

You can define the script on your local machine and then cat and pipe it to the remote machine:

user@host:~/temp> echo "echo 'Test'" > fileForSsh.txt
user@host:~/temp> cat fileForSsh.txt | ssh localhost

Pseudo-terminal will not be allocated because stdin is not a terminal.
stty: standard input: Invalid argument
Test
share|improve this answer
3  
UUOC you can use < –  Iain yesterday
    
Can you modify the example to include sudo -u scriptuser? Would heredoc be usable considering I need to have variables in the script I'd be piping to the machine? –  VoY yesterday
    
I was trying: echo "sudo `cat fileForSsh.txt`" | ssh ... but I keep getting sudo: sorry, you must have a tty to run sudo. –  jas_raj yesterday
    
Although this question may help if you can get the /etc/sudoers file changed –  jas_raj yesterday

Are you aware that you can use sudo to give you a shell where you can run commands as the chosen user?

-i, --login

Run the shell specified by the target user's password database entry as a login shell. This means that login-specific resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed. sudo attempts to change to that user's home directory before running the shell. The com‐ mand is run with an environment similar to the one a user would receive at log in. The Command Environment section in the sudoers(5) manual docu‐ ments how the -i option affects the environment in which a command is run when the sudoers policy is in use.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.