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?
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
\newlineis 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.
You can use as follow:
ssh root@server command -v git || apt install git
apt install git on the local system, not the remote server.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.git on the remote system, not the local system.git.