I'm trying to write something for Bash on the Windows System for Linux that converts ~ to your Windows user directory when passed through a winpath
function. So far, I'm able to retrieve the Windows directory, and convert it to a Unix path, and I'm also able to find the part after /home/[username]/
that gets output by ~
. Where I'm running in to trouble is in concatenating these two.
I've got two variables, like so:
$target_path=/home/jacob/Repositories
$user_path=/mnt/c/Users/Jacob
(In reality I'm retrieving them programmatically, but I don't think that makes a difference.)
I then remove /home/jacob
from $target_path
, leaving it as just /Repositories
.
The goal is to combine $user_path
with the modified $target_path
, so it outputs as:
/mnt/c/Users/Jacob/Repositories
To do this, I'm simply doing:
target_path=$user_path$target_path
But what's happening, for some reason, is it's outputting as:
/RepositoriesJacob
This doesn't make any sense, because when I output $user_path
on it's own, it's correct, and when I output $target_path
on it's own, it's also correct. So it's something in combining these two that's messing it up.
The relevant lines are 8-20 in this gist (full code pasted below).
winpath() {
# get the Windows user path
user_path=$(/mnt/c/Windows/System32/cmd.exe /C echo %HOMEDRIVE%%HOMEPATH%)
# expand the specified path
target_path=$(readlink -f $1)
# change ~ to $user_path (WIP)
if grep -q "^/home/" <<< $target_path; then
# convert Windows-style user path to Unix-style (i.e. from C:\Users\[username] to /mnt/c/Users/[username])
temp_user_path=$(echo "$user_path" | sed -e 's|\\|/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/mnt/\L\1\E/\2|')
# remove /home/[username]/ from $target_path
target_path=$(echo "$target_path" | sed -e 's|^/home/\(.*\)/\(.*\)|/\2|')
# output $temp_user_path for debugging
echo $temp_user_path # correctly outputs
# output $target_path for debugging
echo $target_path # correctly outputs
# combine the variables
echo $temp_user_path$target_path # DOES NOT correctly output (?)
fi
# check if a Windows path is getting parsed
if grep -q "^/mnt/[a-z]/" <<< $target_path; then
# swap /mnt/[a-z]/ with [A-Z]:/ and / with \
echo $(echo "$target_path" | sed -e 's|^\(/mnt/\([a-z]\)/\)\(.*\)|\U\2:\\\E\3|' -e 's|/|\\|g')
else
# return the user's home directory if a Unix path was parsed
echo $user_path
fi
}
EDIT: Okay, so this is weird... Trying this on a Mac, it works fine. Maybe it's some bug with WSL?
EDIT 2: After further testing, it looks like it's something to do with combining the two sed
outputs. If I type out the strings as variables and try combining them, it works just fine. Hmm.
$target_path
, that worked just fine. Any suggestions on how to correct for that? – JacobTheDev Mar 31 '17 at 14:41