-1

I'm on WSL (windows subsystem for Linux) I'm trying to create an alias to run vswhere.exe, which will tell me where devenv.exe is located, and then run that from my ZSH shell.

path1="$(vswhere.exe -property productPath -format value)"

echo $path1

outputs: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\devenv.exe

path2=$(wslpath -a "$path1")

echo $path2

outputs: /mnt/c/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/Common7/IDE/devenv.exe

$path2 contains exactly what i want to execute, except it's not quoted. If I take that string on the console, copy paste it, and surround it with quotes manually, VS executes properly.

Like this: eval '/mnt/c/Program\ Files\ (x86)/Microsoft\ Visual\ Studio/2017/Enterprise/Common7/IDE/devenv.exe'

running: eval $path2 fails since the $path2 has spaces in it.

I've tried this: path3=$(printf %q $path2 | sed -e 's/^M$//')

echo $path3

'mnt/c/Program\ Files\ (x86)/Microsoft\ Visual\ Studio/2017/Enterprise/Common7/IDE/devenv.exe$'

This contains a $ at the end of the string. Trying to do eval $path3 fails with:

zsh: no such file or directory: /mnt/c/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/Common7/IDE/devenv.exe^M

Note the ^M at the end. I've run out of ideas on sed commands and such to make this work and I'm sure there's just some fancy regex or zsh/bash command to make this work properly.

Mark Zuber
  • 69
  • 2
  • 3
  • Why do you need an ending `$` in `$path3`? I believe you don't. An executable is probably ending with `devenv.exe`, not `devenv.exe$`. Or perhaps replace that ending `$` with e.g. `%` or `~` or `_` – Basile Starynkevitch Feb 22 '19 at 05:35
  • I'm not putting the ending $ in $path3. That's the problem. sed or printf appears to be putting it there and I don't know how to _not_ have it there. – Mark Zuber Feb 22 '19 at 05:41
  • You do have a `$` in your `sed` argument. – Basile Starynkevitch Feb 22 '19 at 05:47
  • Removing that doesn't change it: $(printf %q $path2 | sed -e 's/^M//') 'mnt/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2017/Enterprise/Common7/IDE/devenv.exe$' – Mark Zuber Feb 22 '19 at 06:00
  • Your question is unclear, since you don't explain why you want to use `devenv.exe` (which I guess is some Microsoft IDE) from Linux (e.g. your WSL). IMHO that is your main mistake. – Basile Starynkevitch Feb 22 '19 at 06:04
  • I'm trying to launch a windows program on WSL. Finding the path to that program is supported using vswhere.exe. I want to be in WSL as my shell (instead of cmd or powershell) and launch VS just like I can launch other programs (like notepad.exe or vscode). It's definitely not a mistake to want to launch a program from WSL. – Mark Zuber Feb 22 '19 at 06:29
  • But for your own sake you want to avoid spaces in such programs. And I don't understand why you use `devenv`, not `gcc` and/or `emacs`, in your Linux shell script – Basile Starynkevitch Feb 22 '19 at 06:30

2 Answers2

2

You need to quote the expansion of $path2. You don't need eval. You do need to strip the trailing carriage return if it is present. The reason is that if wslpath produces output with a DOS line ending (\r\n), the command substitution strips the trailing newline (\n) character, but not the carriage return (\r) that precedes it, leaving it as an ordinary character.

# Get the path
path2=$(wslpath -a "$path1")
# Strip the trailing carriage return, if present
path2="${path2%$'\r'}"
# Execute the program, quoting the expansion 
# to produce a single shell word for the command name.
"$path2"
chepner
  • 497,756
  • 71
  • 530
  • 681
-1

Read more carefully the bash reference manual. Be aware of quotations and how to use them wisely.

You should consider:

eval '"/mnt/c/Program\ Files\ (x86)/Microsoft\ Visual\ Studio/2017/Enterprise/Common7/IDE/devenv.exe"'

Better yet, get rid of that spaces in system directory madness (MicroSoft is crazy to use them) and have some symlinks like /mnt/c/Program_Files_x86 -> /mnt/c/Program\ Files\ (x86) etc. How to set that up is left as an exercise to the reader.

Actually, I would recommend having your $HOME/bin/ in your $PATH and put a symlink to /mnt/c/Program\ Files\ (x86)/Microsoft\ Visual\ Studio/2017/Enterprise/Common7/IDE/devenv.exe (which I guess is some MicroSoft IDE) in your $HOME/bin/

Your life will be simpler if you avoid like plague spaces (and some other weird characters such as *, (, ), [, ], ;, ? etc...) in file names. Because spaces in command lines are related to globbing and shell expansion.

BTW, I can't understand why you need to use devenv.exe from a Linux script. IMNSHO you should avoid using MicroSoft IDEs from a Linux script. I really believe you should avoid doing this. See this answer, it is relevant to your issue. Don't use Linux like you use Windows. So use Windows the Windows way, and use Linux -and that includes WSL- the Linux way (read about the Unix philosophy).

Regarding usage of sed (or the printf command...) take some time to read the sed(1) man page (and also printf(1)). That documentation is clear enough (but dense).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I appreciate your philosophy, but just because you disagree with why I should be doing something which is totally supported (and in fact the reason for WSL's existence in the first place) doesn't mean it shouldn't be done. – Mark Zuber Feb 22 '19 at 06:31
  • My practical advice is to avoid spaces in filenames. Have a few symlinks to avoid that on Linux (and WSL is some kind of Linux) – Basile Starynkevitch Feb 22 '19 at 06:32
  • I agree with you that spaces in filenames are crazy talk. But even to build the symlink from a script I need to be able to properly reference this string as a findable path in linux. And sed or printf is adding the $ at the end and/or the ^M and my main question is how to remove those in Linux, not the philosophical issue around spaces. If you have guidance on how to help me get the string formatted properly, I appreciate the assistance. Otherwise this dialog isn't very helpful – Mark Zuber Feb 22 '19 at 06:35
  • In the vast majority of cases, spaces in a file name are trivial to handle. You just need to properly quote your parameter expansions. – chepner Feb 22 '19 at 14:40