VS Code - Using Code Runner Extension to Run Programs on Virtual Machine (VM) - visual-studio-code

I develop on Windows using a Linux VM via Vagrant and Virtual Box. I'm trying to figure out how to get the Code Runner extension to run my files on the VM. The biggest hurdle so far is, for a given file, I need to convert from the Windows host path to the Linux guest path.
Background:
The Code Runner extension allows one to map file types to shell commands to run those files. For example,
"java": "cd $dir && javac $fileName && java $fileNameWithoutExt"
tells Code Runner that when I try to run a Java file, it should cd to the directory that contains the file, and compile the file, and then run the compiled file. The mapping from file types to commands is called the code-runner.executorMap which is contained in settings.json. By adding the option
"code-runner.runInTerminal": true
to my settings.json, I can tell Code Runner to run in the integrated terminal. So by simply SSHing into my VM from the integrated terminal via vagrant ssh, I have code runner targeting the virtual machine.
This is where the problem comes in - Code Runner is using my Windows style paths and my Windows file structures as command line arguments to my VM.
For example, suppose my Windows file structure looks like c:\a\b\c\d and my VM has its root in c so that c and d are shared folders. If I want to run a file in d, the command cd $dir will tell my VM to do cd c:\a\b\c\d.
I have thought of workarounds like adding the following to my settings to run python files
"python": "cd \"$(dirname \"$(locate -l1 $fileName)\")\"; python3 $fileName",
This command, which runs on the integrated terminal (the VM) locates and changes to the directory which contains the file which is to be run. It then tells the python3 interpreter to run that file. However, this doesn't always work (e.g. multiple files with the same name), and requires me to update the database that locate depends upon every time I add a file.
There has to be some way to translate my Windows file paths to the paths on the virtual machine (so e.g. c:\a\b\c\d -> /c/d). Perhaps through Vagrant? I would appreciate any help.

I developed a workaround. I would still be interested in a "cleaner" solution.
The workaround is as follows:
Firstly, I wrote a Python script to convert from Windows Paths to paths on my virtual machine. The script takes in the windows path to a file and the file name as arguments.
#pathconverter.py
import sys
windows_path=sys.argv[1]
file_name=sys.argv[2]
path_to_vagrantfile = r"C:\Users\Evan\Google Drive\Development\Vagrantfile"
slashes=path_to_vagrantfile.count("\\")
y=windows_path.split("\\")[slashes:]
linux_path="/vagrant/"+'/'.join(y) + "/" + file_name
print(linux_path)
Thus the following code converts from a windows file location to one on my virtual machine (assuming you saved pathconverter.py at the root of your shared directory, \vagrant :
python3 \"/vagrant/pathconverter.py\" $dirWithoutTrailingSlash $fileName
Therefore, to run most files of various interpreted languages, I just supply the output of this command as an argument to the interpreter. For example, to run a Python script on my VM automatically, I just add the following line to the code-runner.executorMap:
"python": "python3 \"$(python3 \"/vagrant/pathconverter.py\" $dirWithoutTrailingSlash $fileName)\""
Or for Racket/scheme, I just do:
"scheme": "racket \"$(python3 \"/vagrant/pathconverter.py\" $dirWithoutTrailingSlash $fileName)\""

Related

VSCode - remote SSH - can't find code executable in vscode-server directory

I'm using VSCode and the official remote-ssh extension.
I would like to be able to write code /path/to/file in an ssh terminal or in the vscode integrated terminal in a remote window in order to open a file/folder in vscode remote.
I am aware that I can use code --folder-uri=vscode-remote://ssh-remote+ADDRESS/path/to/file from the local machine's terminal, but I want to be able to run a command from within the integrated vscode terminal and any other terminal session where I've ssh'd into the remote machine)
Currently, if I run code from a remote terminal it opens up a new vscode window on the remote machine.
To achieve this goal, in the past I've used the following alias on the remote machine:
alias code="${VSCODE_GIT_ASKPASS_NODE%/*}/bin/code"
Which looks for the code executable in ~/.vscode-server/bin/<COMMIT_ID>/bin before defaulting to the local /bin/code.
I got that alias from this related stackoverflow question.
However, this doesn't seem to work right now.
Upon closer inspection, it appears that there is no code executable in the vscode-server directory.
How can I fix this?
Both machines are running MacOS and visual studio code version f80445acd5a3dadef24aa209168452a3d97cc326, if that's relevant.
I also wanted to be able to run code from the integrated terminal when running VSCode with the "remote ssh" extension. In my case, the "remote" is a Linux box (named "aorus" below), and I want to use VSCode from a laptop running macOS (named "mbp").
As for you, I used to use the VSCODE_GIT_ASKPASS_NODE trick. Recently, I had to change the alias since code (or code-insiders in my case) wasn't available in bin/ anymore. It seems it has been moved to bin/remote-cli. The correct alias (tested with vscode 1.64.2):
alias code="${VSCODE_GIT_ASKPASS_NODE%/*}/bin/remote-cli/code"
If you also want this to work from other ssh sessions (not just inside the integrated terminal), you can create a short script that I called coder (r for "remote") which I have in ~/bin on my remote ("aorus"). Note that you need to be able to reach the local machine from your remote (I do that with Tailscale). The script looks like this:
#! /bin/bash
set -ex
remotehost=$(hostname)
localhost=mbp
cmd="code"
while [ $# -gt 0 ]; do
if [ -f "$1" ]; then
cmd+=" --file-uri \"vscode-remote://ssh-remote+$remotehost$(readlink -f "$1")\""
elif [ -d "$1" ]; then
cmd+=" --folder-uri \"vscode-remote://ssh-remote+$remotehost$(readlink -f "$1")\""
else
cmd+=" $1"
fi
shift
done
exec ssh $localhost -q -t -x "exec bash -l -c '$cmd'"
On my Mac, when running VSCode connected remotely to my Linux box, I can type this in the integrated terminal to open the file main.go present on my remote Linux box:
coder main.go
The reason I have to wrap code in bash -l is due to the fact that ssh, by default, runs in a non-login shell, which means that the ~/.bashrc on my Mac isn't picked up, meaning code isn't in the PATH. The error message looks like this:
bash:1: command not found: code
Another note: there is a shorter syntax documented here:
ssh -q -t -x mbp bash -l -c "code --remote=ssh-remote+aorus main.go"
I don't use this syntax is because this method isn't able to know whether you are opening just a single file (which should be open in the most recent VSCode remote session) or a folder (which should be open as a new VSCode remote session).
Finally, if you are using VSCode Insiders, you can create a symlink so that the command code works on your local machine (in my case, on my Mac):
sudo ln -sf /usr/local/bin/code-insiders /usr/local/bin/code
As already explained by maelvls the path has been changed.
But if you use it outside integrated terminal you will got message
Command is only available in WSL or inside a Visual Studio Code terminal
To avoid this you need to export VSCODE_IPC_HOOK_CLI in your .bashrc .
Use this script in your .bashrc
export VSCODE_IPC_HOOK_CLI=`ls -t /run/user/1012/vscode-ipc-* | head -n1`
alias code="~/.vscode-server/bin/*/bin/remote-cli/code"
If you want to open your file in your current visual studio use -r option.
code -r tes.txt
Note :
I can't call VSCODE_GIT_ASKPASS_NODE so I use full path, it is working well
I don't know if VSCODE_IPC_HOOK_CLI will show in different location, just check it in your integrated terminal visual studio code
tested on remote server Centos 7
local macOS Monterey version 12.2
Visual Studio Code Version: 1.64.2 (Universal)
Commit: f80445acd5a3dadef24aa209168452a3d97cc326
extension : remote-ssh

how to schedule a script created in VScode (WSL) - Python

I have a script that I want to schedule to run each lets say every 10min.
this script downloads a csv file in this folder.
C:\Users\rsharma\scripts\cylance\external_devices
Script name is external_devices.py and I have created it in visual studio code (WSL).
now I know I can use Crontab and windows scheduler to schedule it but nothing seems to be working.
this is my script path
C:\Users\rsharma\scripts\cylance\External_devices.py
these are the crontab entries I have tried
*/10 * * * * /mnt/c/Users/rsharma/scripts/cylance/External_devices.py
*/10 * * * * /usr/bin/python3 /mnt/c/Users/rsharma/scripts/cylance/External_devices.py
windows scheduler entries -
program - C:\WINDOWS\System32\wsl.exe
argument - /mnt/c/Users/rsharma/scripts/cylance/External_devices.py
Please move the script out of "/mnt/c/Users...." directory and copy to another directory in the C drive. The WSL mount point is only available when the lxss Hyper-V WSL is started so will not be mounted unless VSCode is running. It's now much better to use the WSL2 (Ubuntu 20.4) version which you can download from the Microsoft store and then install into as an extension "VSCode Remote Extensions for WSL" which will mount into "/home/username" and is much much faster and feature rich, especially if you plan to use Docker as it is directly integrated.
Install Windows Python into a directory of your choice for example - c:\Python. You will obviously need to install any libraries that the Unix version uses. There will be a binary
c:\Python\Python3.x\python.exe
That will need to be coded into a batch windows command file (xxx.cmd). To run your script change to the directory the script is saved and run the python command.
Example code for xxx.cmd batch file:
cd c:\scriptdirectory
c:\Python\Python3.x\python.exe External_devices.py
Run this on the command line to ensure it works, then schedule in the Windows Scheduler as appropriate.

WSL Interop PATH customization

I have an Ubuntu-18.04 WSL instance installed and have a large set of scripts installed in it at /home/username/bin/scripts.
I have also updated the $HOME/.bashrc, $HOME/.bash_profile, /etc/bash.bashrc, /etc/profile and /etc/environment files to update $PATH to include /home/username/bin/scripts in the path.
*I'm well aware i only usually need it in my $HOME/.bash_profile, lots of places from experimenting
Say I have a script called sampleScript in /home/username/bin/scripts, when i try to run the command:
wsl sampleScript
It gives the error: /bin/bash: sampleScript: command not found
If I open up wsl in interactive mode I can run it just fine, but I would like to be able to expose the script to not be run in interactive mode.
I've tried making an environment variable SPATH='/home/username/bin/scripts' and setting WSLENV=SPATH/p, but it also does not show up if i do wsl echo $PATH.
*I'm doing this all in command line instead of powershell b/c powershell doesn't appear to be able to do wsl echo $PATH at all, it just returns empty
I have also tried: wsl -u username sampleScript; with no luck
Is there a way to customize the PATH for wsl interop mode or am i doing something incorrectly with WSLENV?

Executing subprocess.Popen inside Python script in PyDev context is different than running in terminal

I'm executing this code:
p = subprocess.Popen(['/path/to/my/script.sh','--flag'] , stdin=subprocess.PIPE)
p.communicate(input='Y')
p.wait()
It works when executing it on the shell using "python scriptName.py",
BUT when executing using PyDev in Eclipse, it fails, the reason:
/path/to/my/script.sh: line 111: service: command not found
This bash script "script.sh" contains the following command which causes the error:
service mysqld restart
So "service" is not recognized when running the .sh script from the context of PyDev.
I guess it has to do with some ENV VAR configurations, couldn't find how to do it.
BTW - Using "shell=True" when calling subprocess.Popen didn't solve it.
service usually is located in /usr/sbin, and that this directory isn't on the PATH. As this usually contains administrative binaries and scripts which arn't designed to be run by everyone (only by admins/root), the sbin directories arn't always added to the PATH by default.
To check this, try to print PATH in your script (or add an env command).
To fix it, you could either
set the PATH in your python script using os.setenv
pass an env dict containing the correct PATH to Popen
set the PATH in your shellscript
use the full path in your shellscript
set the PATH in eclipse

Executable file to run java on CentOS 5

I'm trying to make a simple file so I can call it in SSH and it will start my minecraft server.
I tried making a batch file called start.bat with this code:
java -Xmx512M -Xmx512M -jar craftbukkit-1.2.5-R1.0.jar nogui
However, when I run it in SSH:
$ cd /Minecraft/server_1/
$ start.bat
The SSH returns that it is an invalid or unknown command. Is there any other way I can make a quick command/file to start my server? What file extensions would I use to get this working? It works if I paste that java command in SSH and run it, but I'd rather have a file.
The current working directory is not included in your PATH by default because it is a security risk on multiuser systems. (And a potential annoyance even on machines that are single user.) You would use ./start.bat to start the program.
Since you're using Windows naming conventions, I presume you also forgot to set the execution mode bit -- and you probably also forgot the shebang line at the top of the file.
Try this:
#!/bin/sh
java -Xmx512M -Xmx512M -jar craftbukkit-1.2.5-R1.0.jar nogui
Run chmod 500 on this file. (Strictly speaking, 555 could also work, if you didn't mind other people on the machine executing the file. But they don't need to, so don't let them.) See the chmod(1) manpage for more details on the modes -- 1 bits mean executable, 2 bits means writable, and 4 bits means readable -- thus, 5 is executable and readable.
Then, when you want to run the script, run it like this:
cd /Minecraft/server_1
./start.bat
Note the ./ -- that means the shell should start the search for the executable program in the current working directory. (It could be ./bin/start.bat if your current working directory had a bin subdirectory with a start.bat executable file.)
Is start.bat executable? Make sure you have #!/bin/sh as the first line of the file. Also the directory is probably not in in the path, so try this:
$ chmod 555 start.bat
$ ./start.bat