0

I have a bash script that SSHes into 2 machines and runs identical commands.

I'd like to store this in a var, but I'm not sure how to reference the contents of the var when running the command

ssh -o StrictHostKeyChecking=no ubuntu@123.123.123 -i ./travis/id_rsa <<-END
  sudo su;
  ...
  echo "Done!";
END


ssh -o StrictHostKeyChecking=no ubuntu@456.456.456 -i ./travis/id_rsa <<-END
  sudo su;
  ...
  echo "Done!";
END

I tried something like this but it didn't work:

script=$(cat <<-END
  sudo su;
  ...
  echo "Done!";
END
)

ssh -o StrictHostKeyChecking=no ubuntu@123.123.123 -i ./travis/id_rsa $script
ssh -o StrictHostKeyChecking=no ubuntu@456.456.456 -i ./travis/id_rsa $script
bigpotato
  • 26,262
  • 56
  • 178
  • 334
  • It's extremely unclear what you hope for the variable to contain but at the very least you seem to be confused about how to use `su`. See this: https://stackoverflow.com/questions/37586811/pass-commands-as-input-to-another-command-su-ssh-sh-etc – tripleee Jun 29 '18 at 15:39
  • Maybe you want `script='hostname; id'` and then `for host in 123.123.123 456.456.456; do ssh -o etc etc ubuntu@"$host" sudo -s <<<"$script"; done` – tripleee Jun 29 '18 at 15:43
  • `script=$(command)` assigns the standard output of `command` as the value of `script` so this seems like not at all what you want. – tripleee Jun 29 '18 at 15:44
  • 1
    Also https://mywiki.wooledge.org/BashFAQ/050 – tripleee Jun 29 '18 at 15:56

2 Answers2

2

If I am at all able to understand what you are asking, you really don't want to put the commands in a variable.

for host in 123.123.123 456.456.456; do
    ssh -o StrictHostKeyChecking=no ubuntu@"$host" -i ./travis/id_rsa<<-\____here
        sudo -s <<-_________there
            : your script goes here
________there
        echo "Done."
____here
done

If you really wanted to assign a multi-line variable (but trust me, you don't) the syntax for that is simply

script='sudo -s <<\____there
    : your commands
____there
echo "Done."'

But there really is no need to do this, andeit actually complicates things down the line. You see, passing in properly quoted strings as arguments to ssh is extremely tricky - you have the local shell and the remote shell and both require additional quoting or escaping in order to correctly pass through shell metacharacters; and the usual caveats with eval apply, only you are effectively running a hidden eval by way of passing in executable code as a string for the remote shell.

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

I believe you want to do something like this:

cmds="sudo bash -c 'command1; command2; command3;'"
ssh ... "$cmds"
Jonas Bjork
  • 158
  • 3
  • @CharlesDuffy I wouldn't recommend it even in this case, especially without double-quotes around `$cmds`. Consider `cmds="sudo bash -c 'echo cp * /target/dir;'"` -- the `*` will get expanded to a list of files on the local computer before it's sent over ssh! – Gordon Davisson Jun 29 '18 at 21:05
  • @GordonDavisson, oh, you're right -- I missed that the answer wasn't quoting the `"$cmds"` expansion. This is, indeed, bad practice even in the absence of variables substituted in when the command is assigned. – Charles Duffy Jun 29 '18 at 21:12
  • @JonasBjork, are you willing to [edit] your answer to correct that error? – Charles Duffy Jun 29 '18 at 23:07
  • It would be safer with regard to word splitting to use an array instead of a string. – Kusalananda Jun 30 '18 at 14:54