0

I have a script like the following:

#!/bin/bash
SERVER=127.0.0.1
ssh root@$SERVER << EOF
   checkcommand(){
      echo "checking $1"
      command -v $1 || apt install $1
   }
   checkcommand git
EOF

It won't work at all. How can I fix it?

2 Answers 2

1

You need to prevent the variables in the here-document from being evaluated on the local system. You can make it act like a quoted string by putting the end token in quotes.

#!/bin/bash
SERVER=127.0.0.1
ssh root@$SERVER << 'EOF'
   checkcommand(){
      echo "checking $1"
      command -v $1 || apt install $1
   }
   checkcommand git
EOF

This is documented in the Bash Manual section on Here Documents:

If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the character sequence \newline is ignored, and ‘\’ must be used to quote the characters ‘\’, ‘$’, and ’`.

word refers to the token after <<, and delimiter refers to the matching token at the end of the here-doc.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! It works. I never see the difference here. Is there any reference for such subtle syntax?
I've added the documentation.
0

You can use as follow:

ssh root@server command -v git || apt install git

4 Comments

This executes apt install git on the local system, not the remote server.
In my test, the git command exists, so, I forced and, really, the or statement runned the command locally. In a new try, i isolated the command ssh root@server 'command -v git || apt install git' and worked fine, but, your answer responds directly what @D-C wants, maintaining the original code working.
The whole point of the script is to install git on the remote system, not the local system.
I also suspect the posted code is a simplification, and it wants to install other programs, not just git.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.