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, 2018 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, 2018 at 14:30
  • where are ACCOUNT and DOMAIN variables supposed to be resolved? On the remote host, or locally?
    – Tagwint
    Jun 29, 2018 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}') Jun 29, 2018 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, 2018 at 16:48

1 Answer 1


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] [=======

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .