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

I apologize if the title doesn't quite describe what I'm looking for. Please edit if possible.

I have a bash script that does the following:

serveruser="root"
serverip=1.2.3.4
serverpath="/var/www"


ssh "$serveruser"@"$serverip" /bin/bash <<\EOF
mkdir -p "$serverpath/mysqldumps/"
cd "$serverpath/mysqldumps/"
domainname=somedomain.com
mysqldump -h 192.168.1.4 -udba -ppassword -c --add-drop-table --add-locks --create-options --databases --quick --lock-tables $domainname > $domainname.sql
EOF

My problem is that the multiple lines I am "feeding" to ssh don't parse the variables I set before. This is obviously because the variables aren't set on the remote machine, only in my local shell. How could I pass these variables or possibly pass multiple lines to ssh in a different way?

share|improve this question
    
Why not do it the other way as in echo "cmd $var | ssh user@remote bash? –  Zoredache Apr 18 '13 at 18:26

2 Answers 2

up vote 2 down vote accepted

The way you're escaping the here-doc word is preventing variable substitution. Contrast

cat <<\END
$PATH
$LOGNAME
END

versus

cat <<END
$PATH
$LOGNAME
END

update

On closer inspection, I see you're setting a variable in the heredoc. That should not be expanded on the local machine, so you need to escape those in the mysqldump command. Try this:

ssh "$serveruser"@"$serverip" <<EOF
mkdir -p "$serverpath/mysqldumps/"
cd "$serverpath/mysqldumps/"
domainname=somedomain.com
mysqldump -h 192.168.1.4 -udba -ppassword -c --add-drop-table --add-locks --create-options --databases --quick --lock-tables \$domainname > \$domainname.sql
EOF
share|improve this answer
    
For some reason I get strange things happening when I don't use the backslash. For example, my shell seems to pause for over a minute and I get an error later on that mysql can't connect to the server, as if the commands were actually running locally and not on the remote ssh server. I have verified that within the here-doc setting the serverpath var works as expected. I need to be able to set out outside of that here-doc though. –  senorsmile Apr 18 '13 at 18:34
1  
What's happening is that you're logging on to the remote server, running bash non-interactively, and that exits right away. Then the commands in the heredoc get executed. Simply remove "/bin/bash" from the ssh command and it will execute the heredoc remotely. –  glenn jackman Apr 18 '13 at 18:41
    
I added /bin/bash to ssh because without it I get the error: Pseudo-terminal will not be allocated because stdin is not a terminal. That error doesn't seem to actually break anything though. –  senorsmile Apr 18 '13 at 18:45
    
Use the ssh options -t or -T to force/disable a pseudo-tty, depending on your needs. That will at least take care of the error message. –  glenn jackman Apr 18 '13 at 19:27
    
Thanks for the tip about -T. At first I thought removing /bin/bash solved my problems... but on further testing it's still not expanding the variables within the heredoc. –  senorsmile Apr 18 '13 at 21:36

You need to quote the whole command.. and no need to quote the vars like that put them like ${var}

serveruser="root"
serverip=1.2.3.4
serverpath="/var/www"


ssh ${serveruser}@${serverip} "/bin/bash <<\EOF
mkdir -p ${serverpath}/mysqldumps/
cd ${serverpath}/mysqldumps/
EOF"
share|improve this answer
    
I always quote just based on info like : mywiki.wooledge.org/BashPitfalls#cp_.24file_.24target . –  senorsmile Apr 18 '13 at 18:14
    
$( ) runs its inner commands in a subshell, so referring to any variable like that doesn't seem to work in bash. –  senorsmile Apr 18 '13 at 18:16

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.