Type the first line in bash and then echo that variable, this is what you'll see:
$ tmpdir=/cygdrive/c/workdir\ \(newco\,\ LLC\)
$ echo $tmpdir
/cygdrive/c/workdir (newco, LLC)
If it's not clear yet what's the culprit, add echo
at the beginning of your second line and wrap it in double quotes. You'll see what command is actually executed:
$ echo "tail -n +2 $tmpdir/workfile.txt > $tmpdir/workfile2.txt"
tail -n +2 /cygdrive/c/workdir (newco, LLC)/workfile.txt > /cygdrive/c/workdir (newco, LLC)/workfile2.txt
You have properly escaped variable assignment, but that's not enough. Bash performs simple substring substitution, thus inserting additional spaces and breaking your command.
As @savanto suggested in his answer, you can wrap variables in double quotes to ensure that extra spaces aren't treated as argument separators. This line:
tail -n +2 "${tmpdir}/workfile.txt" > "${tmpdir}/workfile2.txt"
will look like this after variable substitution:
tail -n +2 "/cygdrive/c/workdir (newco, LLC)/workfile.txt" > "/cygdrive/c/workdir (newco, LLC)/workfile2.txt"
This is the most common and preferred way of solving that issue. If you desperately want to avoid double quotes, you can try double escaping: first when assigning, then after substitution.
$ tmpdir=/cygdrive/c/workdir\\\ \\\(newco\\\,\\\ LLC\\\)
$ echo $tmpdir
/cygdrive/c/workdir\ \(newco\,\ LLC\)
Quick explaination of triple backslashes: a backslash means: "treat next character as a regular character, ignore any special meaning" (i.e. escape it). First backslash is an escape character, so second one will be treated as a backslash character, not escape character. Thus, double backslash produces a single backslash. Third one simply escapes following character, like space or parenthesis. For example a\\\ b
will become a\ b
.
Now if we substitute variables in your command, it will be escaped properly:
tail -n +2 /cygdrive/c/workdir\ \(newco\,\ LLC\)/workfile.txt > /cygdrive/c/workdir\ \(newco\,\ LLC\)/workfile2.txt