AsmCoder8088
AsmCoder8088

Reputation: 51

Line break mystery when using quotes around variable

I wrote a simple script, the whole purpose of which is to simply create a link between two different cygwin directories. It should be very simple, but since $LOCALAPPDATA can contain spaces, it wound up being far more difficult than I originally envisioned.

Here is the script:

#!/bin/sh

echo "Unlinking any existing data link..."
unlink /usr/local/astrometry/shared_data 2>/dev/null

echo "Generating link between astrometry shared_data..."

my_dir=`cygpath -u $LOCALAPPDATA/cygwin_ansvr/usr/share/astrometry/data`
echo $my_dir
my_test=`echo $my_dir`
echo $my_test

# Note here, if I use $my_dir rather than $my_test, it introduces a LINE BREAK!
ln -s "$my_test" /usr/local/astrometry/shared_data

exit 0

So, if I run the above script, here is the output:

Unlinking any existing data link...
Generating link between astrometry shared_data...
/cygdrive/c/Users/Dwight Towler/AppData/Local/cygwin_ansvr/usr/share/astrometry/data
/cygdrive/c/Users/Dwight Towler/AppData/Local/cygwin_ansvr/usr/share/astrometry/data

And the link is formed as such:

lrwxrwxrwx  1 Dwight Towler None  84 Sep 22 02:56 shared_data -> /cygdrive/c/Users/Dwight Towler/AppData/Local/cygwin_ansvr/usr/share/astrometry/data
drwx------+ 1 Dwight Towler None   0 Sep 22 02:56 .

The above is the desired link (no line break).

Now, if I replace $my_test with $my_dir in the ln -s call, I instead wind up with this:

lrwxrwxrwx  1 Dwight Towler None  84 Sep 22 02:55 shared_data -> /cygdrive/c/Users/Dwight
Towler/AppData/Local/cygwin_ansvr/usr/share/astrometry/data
drwx------+ 1 Dwight Towler None   0 Sep 22 02:55 .

Notice the line break? I cannot figure out where that is coming from, especially since I put quotes around the variables in the ln -s call.

It is especially puzzling since the output of the echo command seems to indicate that both variables have the same content:

echo $my_dir
/cygdrive/c/Users/Dwight Towler/AppData/Local/cygwin_ansvr/usr/share/astrometry/data
echo $my_test
/cygdrive/c/Users/Dwight Towler/AppData/Local/cygwin_ansvr/usr/share/astrometry/data

Any ideas on what is going on?

Upvotes: 0

Views: 121

Answers (1)

dash-o
dash-o

Reputation: 14452

That difference in values between 'my_dir' and 'my_test' is the result of using command substitution (my_test=echo $my_dir) to copy the my_dir to my_test. This construct will result in any consecutive white spaces (newline included) replaced with a single space.

As per man page, this command substitution, will result in the value of 'my_dir' being split by the value of IFS (by default - white spaces - spaces, tabs and new line) into words, and than the individual words are printed with a single space between them. Assuming original string contained new lines (or multiple spaces between words) - those will all get converted into a single space.

Consider the following assignment, which will result in embedded newline (between the 'first' and 'second). Using the unquoted "echo" will replace the newline with a space.

A="first
second"
echo "NO QUOTE"
echo $A
echo "QUOTED"
echo "$A"
echo "----"

The output will be

NO QUOTE
first second
QUOTED
first
second
----

Bottom line, the new line is presented in the original string ('my_dir'), and is replaced by space in the echo statement, because of the shell word/command substitution.

Upvotes: 1

Related Questions