Using Chocolatey VS Code from within WSL Ubuntu - bash

I cannot get VS Code code.exe to run properly within WSL. (I found a connected question here, but it does not solve this issue - Launch VS Code from WSL Bash).
Within WSL (any distro) we can access any executables on Windows. e.g.
alias chrome="\"/mnt/c/Program Files/Google/Chrome/Application/chrome.exe\"" # Open Chrome from WSL
alias notepad++="\"/mnt/c/Program Files/Notepad++/notepad++.exe\"" # Open Notepad++
Typing chrome in bash will open Chrome and notepad++ ~/.bashrc would open .bashrc in Notepad++
This all works great.
However, I have hit a problem with code.exe provided by the choco inst VisualStudioCode installation. When I try:
alias vscode="\"/mnt/c/ProgramData/chocolatey/bin/code.exe\""
This fails really badly.
[main 2021-01-24T18:44:17.966Z] update#setState idle
(node:20404) Electron: Loading non-context-aware native module in renderer: '\\?\C:\tools\vscode\resources\app\node_modules.asar.unpacked\vscode-sqlite3\build\Release\sqlite.node'. This is deprecated, see https://github.com/electron/electron/issues/18397.
(node:20404) Electron: Loading non-context-aware native module in renderer: '\\?\C:\tools\vscode\resources\app\node_modules.asar.unpacked\spdlog\build\Release\spdlog.node'. This is deprecated, see https://github.com/electron/electron/issues/18397.
(node:18692) Electron: Loading non-context-aware native module in renderer: '\\?\C:\tools\vscode\resources\app\node_modules.asar.unpacked\spdlog\build\Release\spdlog.node'. This is deprecated, see https://github.com/electron/electron/issues/18397.
So, I can ignore that and just use code.exe within Ubuntu (as WSL will scan the path for executables). This sort of works but with the following error:
'\\wsl$\Ubuntu-20.04\home\boss'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory.
VS Code does open, but if put a filename as an argument that file fails to open (while noting that for the notepad++ example, all files open perfectly run with the above alias).
It seems to be saying that code.exe can't support UNC paths, but it does support UNC paths as I can see from PowerShell. code.exe \\HPEnvy\Drive-D\test.txt opens perfectly.
It would really round out my WSL setup to be able to open code that I'm working on seamlessly with VS Code. Does anyone have an idea why this might be happening / how to fix?

My installation has a shell script for launching VSCode in ../Microsoft VS Code/bin/code. I'm fairly certain that it is installed with VSCode, but there's a chance it comes from the "Remote - WSL" extension.
Is that present in your installation? If so, add that bin directory to your path (the full installer does this automatically). Then just use code rather than code.exe to launch from within WSL.
If not, first make sure the "Remote - WSL" extension is installed in VSCode (or better yet, the "Remote Development" extension pack, which includes the WSL support). If it's still not there after that, here are the contents of the script that should live in VSCode/bin/code:
#!/usr/bin/env sh
#
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
if [ "$VSCODE_WSL_DEBUG_INFO" = true ]; then
set -x
fi
COMMIT="ea3859d4ba2f3e577a159bc91e3074c5d85c0523"
APP_NAME="code"
QUALITY="stable"
NAME="Code"
DATAFOLDER=".vscode"
VSCODE_PATH="$(dirname "$(dirname "$(realpath "$0")")")"
ELECTRON="$VSCODE_PATH/$NAME.exe"
IN_WSL=false
if [ -n "$WSL_DISTRO_NAME" ]; then
# $WSL_DISTRO_NAME is available since WSL builds 18362, also for WSL2
IN_WSL=true
else
WSL_BUILD=$(uname -r | sed -E 's/^[0-9.]+-([0-9]+)-Microsoft.*|.*/\1/')
if [ -n "$WSL_BUILD" ]; then
if [ "$WSL_BUILD" -ge 17063 ]; then
# WSLPATH is available since WSL build 17046
# WSLENV is available since WSL build 17063
IN_WSL=true
else
# If running under older WSL, don't pass cli.js to Electron as
# environment vars cannot be transferred from WSL to Windows
# See: https://github.com/microsoft/BashOnWindows/issues/1363
# https://github.com/microsoft/BashOnWindows/issues/1494
"$ELECTRON" "$#"
exit $?
fi
fi
fi
if [ $IN_WSL = true ]; then
export WSLENV="ELECTRON_RUN_AS_NODE/w:$WSLENV"
CLI=$(wslpath -m "$VSCODE_PATH/resources/app/out/cli.js")
# use the Remote WSL extension if installed
WSL_EXT_ID="ms-vscode-remote.remote-wsl"
ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --locate-extension $WSL_EXT_ID >/tmp/remote-wsl-loc.txt 2>/dev/null </dev/null
WSL_EXT_WLOC=$(cat /tmp/remote-wsl-loc.txt)
if [ -n "$WSL_EXT_WLOC" ]; then
# replace \r\n with \n in WSL_EXT_WLOC
WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode.sh
"$WSL_CODE" "$COMMIT" "$QUALITY" "$ELECTRON" "$APP_NAME" "$DATAFOLDER" "$#"
exit $?
fi
elif [ -x "$(command -v cygpath)" ]; then
CLI=$(cygpath -m "$VSCODE_PATH/resources/app/out/cli.js")
else
CLI="$VSCODE_PATH/resources/app/out/cli.js"
fi
ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$#"
exit $?
Permissions on the file are 0777. And, as mentioned above, it should be in your path.

Related

How to run a command on WSL startup using WSL config files?

I added these lines in my WSL settings files
C:\Users\reynadan\.wslconfig:
[boot]
command=bash /home/reynadan/scripts/startup.sh
/etc/wsl.conf:
[boot]
command=bash /home/reynadan/scripts/startup.sh
/home/reynadan/scripts/startup.sh
#!/bin/bash
# Run wsl-vpnkit if not already connected or running
currentlyRunningWsl=$(wsl.exe -l --running | iconv -f UTF16 -t UTF8 | grep wsl-vpnkit | wc -l)
if [[ $currentlyRunningWsl -eq 0 ]]; then
wsl.exe -d wsl-vpnkit service wsl-vpnkit start
fi
# Start Docker daemon automatically when logging in if not running.
RUNNING=`ps aux | grep dockerd | grep -v grep`
if [ -z "$RUNNING" ]; then
sudo dockerd > /dev/null 2>&1 &
disown
fi
NOW=$(date)
echo WSL booted at $(/bin/date +'%Y-%m-%d %H:%M:%S') >> /home/reynadan/wslBootHistory.txt
echo 'startup lanched'
I closed with wsl --shutdown and waited more than 8 seconds before running it again, but /home/reynadan/wslBootHistory.txt is still empty and docker is not running.
How do I make sure WSL runs my script on startup?
As noted in the comments, you are on Windows 10. However, the information in the comments is a bit outdated -- The boot.command feature does now work on Windows 10, but you need the absolute latest release (including optional updates) of both Windows 10 and WSL installed.
First, confirm that your system is running the November "Cumulative Update Preview". If you are, then your UBR (update-build-revision) will be at 2311 or higher. From PowerShell:
(Get-ComputerInfo).WindowsUBR
If it is lower than 2311, then:
First, make sure your system is otherwise completely up-to-date.
Go to Settings -> Check for Updates and press the Check for Updates button.
If you are fully updated on Windows 10 (but still running less than UBR 2311) you should see "2022-11 Cumulative Update Preview for Windows 10 Version 22H2 for x64-based Systems (KB5020030)" available as an optional update. Install it and reboot when prompted.
With that in place, you should now be able to update to the Store version of WSL with a simple:
wsl --update
wsl --version
After the update, you should be at:
WSL version: 1.0.0.0
... or later.
A reboot at this point is recommended for all features to work properly, but not strictly required.
At this point, you should have access to the /etc/wsl.conf's [boot].command feature.
If for some reason it's still not working, then I would recommend removing the script from the equation to troubleshoot. Try something like command=service cron start and see if the Cron service starts when you restart WSL.
Note that this new update also brings a number of other new WSL2 features to Windows 10 users, including:
Systemd support
WSLg: The ability to run Linux GUI applications in WSL2
The --mount argument for adding additional Windows's drives and partitions (including those with other filesystems or even raw partitions).

Bash on Windows - alias for exe files

I am using the Bash on Ubuntu on Windows, the way to run bash on Windows 10. I have the Creators update installed and the Ubuntu version is 16.04.
I was playing recently with things as npm, node.js and Docker and for docker I found it is possible to install it and run it in windows and just use the client part from bash, calling directly the docker.exe file from Windows's Program Files files folder. I just update my path variable to include the path to docker as PATH=$PATH:~/mnt/e/Program\ Files/Docker/ (put in .bashrc) and then I am able to run docker from bash calling docker.exe.
But hey this bash and I dont want to write .exe at the end of the commands (programs). I can simply add an alias alias docker="docker.exe", but then I want to use lets say docker-compose and I have to add another one. I was thinking about adding a script to .bashrc that would go over path variable and search for .exe files in every path specified in the path variable and add an alias for every occurance, but it does not seem to be a very clean solution (but I guess it would serve its purpose quite well).
Is there a simple and clean solution to achieve this?
I've faced the same problem when trying to use Docker for Windows from WSL.
Had plenty of existing shell scripts that run fine under Linux and mostly under WSL too until failing due to docker: command not found. Changing everywhere docker to docker.exe would be too cumbersome and non-portable.
Tried workaround with aliases in ~/.bashrc as here at first:
shopt -s expand_aliases
alias docker=docker.exe
alias docker-compose=docker-compose.exe
But it requires every script to be run in interactive mode and still doesn't work within backticks without script modification.
Then tried exported bash functions in ~/.bashrc:
docker() { docker.exe "$#"; }
export -f docker
docker-compose() { docker-compose.exe "$#"; }
export -f docker-compose
This works. But it's still too tedious to add every needed exe.
Finally ended up with easier symlinks approach and a modified wslshim custom helper script.
Just add once to ~/.local/bin/wslshim:
#!/bin/bash -x
cd ~/.local/bin && ln -s "`which $1.exe`" "$1" || ln -s "`which $1.ps1`" "$1" || ln -s "`which $1.cmd`" "$1" || ln -s "`which $1.bat`" "$1"
Make it executable: chmod +x ~/.local/bin/wslshim
Then adding any "alias" becomes as easy as typing two words:
$ wslshim docker
+ cd ~/.local/bin
++ which docker.exe
+ ln -s '/mnt/c/Program Files/Docker/Docker/resources/bin/docker.exe' docker
$ wslshim winrm
+ cd ~/.local/bin
++ which winrm.exe
+ ln -s '' winrm
ln: failed to create symbolic link 'winrm' -> '': No such file or directory
++ which winrm.ps1
+ ln -s '' winrm
ln: failed to create symbolic link 'winrm' -> '': No such file or directory
++ which winrm.cmd
+ ln -s /mnt/c/Windows/System32/winrm.cmd winrm
The script auto picks up an absolute path to any windows executable in $PATH and symlinks it without extension into ~/.local/bin which also resides in $PATH on WSL.
This approach can be easily extended further to auto link any exe in a given directory if needed. But linking the whole $PATH would be an overkill. )
You should be able to simply set the executable directory to your PATH. Use export to persist.
Command:
export PATH=$PATH:/path/to/directory/executable/is/located/in
In my windows 10 the solution was to install git-bash and docker for windows.
in this bash, when I press "docker" it works
for example "docker ps"
I didnt need to make an alias or change the path.
you can download git-bash from https://git-scm.com/download/win
then from Start button, search "git bash".
Hope this solution good for you

How to access c:\ on a windows machine with gitlab runner and bash as the shell

I have a gitlab runner running on a Windows Server 2012 machine.
I have installed win-bash and added the location of the bash executable to the system path.
I have configured the runners config.toml file to use bash for the shell
I have a python script stored on the machine that I need to run as part of the build process. This script is stored on the windows machine and is located at c:\path\to\script.py
The first line in my build script prints the working directory pwd and returns this: /home/gitlab-runner/builds/2b321e5b/0/Firmware/PSoC5LP
My question is this: How do I get access to the C:\ drive?
I am running on a windows machine, and starting bash from any other terminal (cmd.exe, powershell, running the bash.exe directly) puts me into the standard windows directory structure from wherever I start bash:
Microsoft Windows [Version 6.2.9200]
(c) 2012 Microsoft Corporation. All rights reserved.
C:\Users\Administrator\Desktop>bash
bash$ pwd
C:/Users/Administrator/Desktop
bash$ cd /
bash$ pwd
C:/
bash$ cd /home
bash: /home: No such file or directory
bash$ ls
$Recycle.Bin ProgramData
BOOTNXT System Volume Information
Documents and Settings Users
Miniconda2 Windows
Multi-Runner bootmgr
PerfLogs cygwin64
Program Files gitrepos
Program Files (x86) pagefile.sys
bash$
no /home/, not a standard linux directory structure in sight. Because of this, my build scripts fail since they are not able to access the files via there absolute path (I don't even know what their relative paths would look like in the runners bash context)
here is the relevant portion of my build script:
#!/bin/bash
echo "build script executing"
pwd
echo "ls /"
ls /
echo "***assembling the LyteByte asm files"
# move to the LyteByteAssember directory
cd ./LyteByteAssembler/
ASSEMBLY_FILE="LyteByteAssembly.lbasm"
MERGE_FILE="merge.lbasm"
OUTPUT_FILE="../BootloaderProj.cydsn/lytebyte_prog_mem_init.c"
TEMP_DIR="./"
PREPROCESSOR_DIRECTORY="c:/gitrepos/ArcherTools/LyteByteAsembler/LyteBytePreProcessor.py"
echo $PREPROCESSOR_DIRECTORY $ASSEMBLY_FILE $MERGE_FILE $TEMP_DIR
python "$PREPROCESSOR_DIRECTORY" "$ASSEMBLY_FILE" "$MERGE_FILE" "$TEMP_DIR"
if [ $? -eq 0 ]
then
echo "Preprocessing succeeded!"
else
echo "Preprocessing failed, process cancelled"
exit 1
fi
and here is a sample output from the runner:
gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on ip-172-31-7-232...
Fetching changes...
HEAD is now at d51e873 hjkj
From https://thing.githost.io/Firmware/PSoC5LP
d51e873..d77e88b CI -> origin/CI
Checking out d77e88b0 as CI...
Previous HEAD position was d51e873... hjkj
HEAD is now at d77e88b... ;jkblkn .,/p
$ bash ./build_script.sh
build script executing
/home/gitlab-runner/builds/2b321e5b/0/Firmware/PSoC5LP
ls /
bin
boot
cgroup
dev
etc
home
lib
lib64
local
lost+found
media
mnt
opt
proc
root
run
sbin
selinux
srv
sys
tmp
usr
var
***assembling the LyteByte asm files
c:/gitrepos/ArcherTools/LyteByteAsembler/LyteBytePreProcessor.py LyteByteAssembly.lbasm merge.lbasm ./
python: can't open file 'c:/gitrepos/ArcherTools/LyteByteAsembler/LyteBytePreProcessor.py': [Errno 2] No such file or directory
Preprocessing failed, process cancelled
It depends on which software you've installed:
If you've installed Git for windows by selecting Git Bash, then you can open Git Bash terminal and browse C: Drive or D: Drive by doing:
cd /c/
cd /c/Windows/
cd /d/
If you've installed cygwin, then you've to do:
cd /cygdrive/c/
Check your manual for win-bash

How to check if subversion is installed using Shell Script on mac

I am writing a little shell script to help setup a production/development environment for some of our software and part of it requires subversion.
I need a way to check if subversion is installed on a *nix(usually mac) machine.
I was thinking of checking if export SUBVERSION_HOME=/opt/subversion exists in .profile since that is what the devs use here, but are there any more concrete ways?
You could do something crude:
which svn
In a test:
if [[ -n $(which svn) ]]; then
# do something
fi
Caveat: this would fail in the very unlikely even that someone has a svn installed that is not actually Subversion.
Something simple like this maybe?
which svn > /dev/null
if [ $? -eq 1 ]; then
echo "subversion is not installed"
exit 1
fi

Sourcing rvm from my Ubuntu .profile only works manually, not at login

I'm having trouble getting the Ruby Version Manager rvm to source from my Ubuntu 10.04 .profile. The code:
[[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"
...never does what I expect it to (i.e. give me the rvm program when I open a new shell or start a new session); but if I execute
source .profile
in a new shell after logging in, it works! Why will it work when I manually source it, but not automatically at login?
It would appear that Ubuntu handles it's logon scripts differently than most other linux distros
http://ubuntuforums.org/showpost.php?p=9127226&postcount=6
The above post has hints that GDM logins in Ubuntu don't process .bash_profile or .profile the way most other linux distros do. I have had to put the line loading RVM in the ~/.bashrc and that has not caused any problems yet.
Sourcing $HOME/.rvm assumes you have installed RVM a single user, specially, the user whose home directory is $HOME. Likely, on your Ubuntu system, RVM has been installed system wide, and thus you must source the RVM scripts as such:
In your .bashrc file add:
\# Set rvm path
[[ -s "/usr/local/rvm/scripts/rvm" ]] && source "/usr/local/rvm/scripts/rvm"
before this line; this line will exit and not execute anything past it, which is fine for interactive logins, bit would be a problem is you are using non-interactive SSH logins for automation purposes.
\# If not running interactively, don't do anything
[ -z "$PS1" ] && return
The RVM installation page has a series of things to check to test the initialization of RVM. Read the "Troubleshooting your Install" section at the end of the RVM installation page.
Also, here's a description of how Bash reads its startup files which can help with this sort of problem.
I had a problem with Atom editor not picking up RVM environment and thus not finding rubocop command on Ubuntu 16.04. But the problem was not there when I started Atom from gnome terminal. What I've found was that RVM script ~/.rvm/scripts/rvm that you're supposed to be loading in your .profile has these lines at the beginning:
if
builtin test -n "${BASH_VERSION:-}" -o -n "${ZSH_VERSION:-}" -o -n "${KSH_VERSION:-}"
then
...
else
return 0
fi
Strangely, when executed at login, I've found $BASH_VERSION to be empty (while in gnome terminal it's sth like 4.3.46(1)-release), so the script would do early return leaving RVM not loaded properly. I tried to set BASH_VERSION to whatever and it worked fine.
Here is the complete code from my .profile that loads RVM:
local rvm_home="${HOME}/.rvm"
export PATH="$PATH:${rvm_home}/bin"
if [ -z "$BASH_VERSION" ]; then
export BASH_VERSION=4
fi
source "${rvm_home}/scripts/rvm"

Resources