self.
self.

Reputation: 1752

How can I execute all script parameters that use here doc?

I have a simple script, which I use throughout my code base, called sshpass.

#!/bin/bash

expect << EOF
spawn $@
expect {
    "*assword" {
        send "$SSHPASS\n"
    }
}
expect eof
EOF

The way I'm currently utilizing this script is like this -

./sshpass scp archive.tgz $SERVER:$DIR

This works quite well when the SSH commands are one-liners. My issue is when I attempt to execute a command through sshpass that uses a here doc.

./sshpass ssh $user@$server /bin/bash << EOF
    echo "do this..."
    echo "do that..."
    echo "and the other..."
EOF

The above fails because $@ only parses out ssh $user@$server /bin/bash.

Please no comment with regards to how I'm handling my SSH authentication. When forced to use Cygwin there are specific things, such as key authentication and administrative privileges, that simply do not work.

Upvotes: 0

Views: 1861

Answers (1)

Eric Renouf
Eric Renouf

Reputation: 14500

The heredoc will replace stdin for your script. If you want it to be accessed as a parameter, use command substitution like

./sshpass ssh $user@$server /bin/bash $(cat << EOF
    echo "do this..."
    echo "do that..."
    echo "and the other..."
EOF
)

although that probably won't end up doing exactly what you want, because it will be passing each word as it's own positional argument, so you will be running

ssh $user@$server echo "do this..." echo "do that..." echo "and the other..."

which will have the first echo get all the rest as arguments. You'll need semi colons at the end of each command, and to have quotes around the whole thing so you don't do some of it remotely and some of it locally. So I should have recommended it as:

./sshpass ssh $user@$server /bin/bash "$(cat << EOF
    echo 'do this...';
    echo 'do that...';
    echo 'and the other...'
EOF
)"

but this still gives me an uneasy feeling as it's very likely easy to "do the wrong thing" with something like this

Upvotes: 5

Related Questions