I'm creating a script to migrate some data between servers.

My headache:

( ... )
ssh -t -i ${KEY} ${USER}@${HOST} "cd /home/${ACCOUNT}/var/${DOMAIN}/ && tar cf - mail/ -P | pv -s $(du -sb mail/ | awk '{print $1}') | gzip > mail.tar.gz"

This command returns something like "I can't find mail folder", and I think I know why.

This comand is evaluated before the ssh connection pv -s $(du -sb mail/ | awk '{print $1}'), and the mail folder dont exists in the first server. But if I hardcode the current byte size the script will work.

How can I bypass this situation?

I would use ' but is already being use in '{print $1}', also tried to create another variable to acomodate something like 'pv -s $(du -sb mail/ | awk \'{print $1}\') ' but still no luck, I've tried so many possibilites with normal and double quotes.

PS: Sorry for my "engrish"

Offtopic: I would love if someone points me to some good article(or some crucial keyword to search for) to explain/show all the possibilites to declarate, display and evaluate variables, I don't know the right terminology. Like ${var} and $var, what echo does when you use " or ', and how to escape duplicated quotes, double quotes, concatenation, etc...

Full script example:

printf "\n\n"
echo "********************************  INTERWORX --> CPANEL  *************************************"
printf "\n\n"

# ----------------

printf " ► ---------------------- [ ${HOST} ]\n"
printf " ►►---------------------- \n"

ssh -t -i ${KEY} ${USER}@${HOST} "cd /home/${ACCOUNT}/var/${DOMAIN}/ && tar cf - mail/ -P | pv -s \$(du -sb mail/ | awk '{print $1}')  | gzip > mail.tar.gz"

printf "\n ►►► ------------ [ mail.tar.gz ]\n\n"

scp -i ${KEY} ${USER}@${HOST}:/home/${ACCOUNT}/var/${DOMAIN}/mail.tar.gz .
                          ( ... )
  • Escape any $ that you don't want to expand with \. – Jesse_b Jun 29 '18 at 14:28
  • If I excape like this ssh-code plus pv -s \$(du -sb mail/ | awk '{print $1}') I get pv: (stdin):reading error: Is a directory – kpuccino Jun 29 '18 at 14:30
  • where are ACCOUNT and DOMAIN variables supposed to be resolved? On the remote host, or locally? – Tagwint Jun 29 '18 at 14:41
  • 2
    Well, to follow on from @Tagwint, where do you expect $(du -sb mail/ | awk '{print $1}') to be evaluated? I suspect what you want is \$(du -sb mail/ | awk '{print \$1}') – steeldriver Jun 29 '18 at 15:44
  • 2
    You should escape $1 part of awk arguments too: to \$1 @steeldriver provided that in his comment Your example shows it is still not escaped – Tagwint Jun 29 '18 at 16:48

Since you mentioned debugging options in your comments, I think this rather deserves answer like this:

Use set -x as the very first command in the sequence

ssh -t -i ${KEY} ${USER}@${HOST} "set -x ; cd /home/${ACCO ....."

this clearly shows the failure point in your case:

not escaped $1

    ++ du -sb mail/
    + pv -s 12314 mail/   # <<< awk printed all the line instead of expected just 1st column with size and that ruined the command
    pv: mail/: read failed: Is a directory

versus escaped

 ++ du -sb mail/
 + pv -s 12314    # <<< pv gets expected number
      10kiB 0:00:00 [ 184MiB/s] [=======

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.