Home > database >  Sending a Variable with Linebreaks in SSH When I'm Also Piping in a Tarball
Sending a Variable with Linebreaks in SSH When I'm Also Piping in a Tarball

Time:06-29

I work with large data sets and periodically back them up to an archival server. When I run out of space, the workflow for sending folder looks like this:

tar cvf - dirname/ | ssh ${ARCHIVER} "cat > ${ARCHIVE}/dirname.tar"

However, given that I cannot ls into a tarball to see what is there. I also plan on sending a limited tree of the contents for each archive. As a standalone sequence, that would look like this.

contents="$(tree -L 2 dirname)"
echo "${contents}" | ssh ${ARCHIVER} "cat > ${ARCHIVE}/dirname_contents.log"

I would like to wrap these up into one ssh session because I don't want to have to enter multiple passwords. I also don't have any admin rights, so extra packages and special ssh key things are not options. I've tried about a billion ways to send the contents file in the first ssh session, but it always turns the linebreaks to spaces, no matter how many quotes I fill it all with. My only guess is to turn all the linebreaks into weird characters before sending, then change them back at the end of the ssh session. Any better ideas?

CodePudding user response:

You can use ssh with connection sharing:

TMPL=/tmp/sshctl/"%L-%r@%h:%p"
mkdir -p /tmp/sshctl
ssh -nNf -o ControlMaster=yes -o ControlPath="${TMPL}" user@host

cmd1 | ssh -o ControlPath="${TMPL}" user@host cmd2
ssh -o ControlPath="${TMPL}" user@host cmd3
...

ssh -o ControlPath="${TMPL}" -O exit user@host

See ssh documentation for details.

CodePudding user response:

Here's how it could be done with sed, if anyone is interested. I replace the linebreaks with / because / is an invalid character in linux directory names, so it shouldn't show up otherwise.

contents=$(tree -L 2 dirname} | sed ':a;N;$!ba;s.\n./.g') # Create contents info, replace linebreaks with /
tar cvf - ${archName}/ | ssh ${ARCHIVER} "cat > ${ARCHIVE}/dirname.tar; echo \"${contents}\" | cat > ${ARCHIVE}/dirname_contents.log; sed -i \"s./.\\n.g\" ${ARCHIVE}/dirname_contents.log"
  • Related