23

Something I love about VS Code is that when I am using a terminal in WSL, I can run code file.txt, and it will open that file with VS Code on my local using the WSL remote extension.

Is it possible to do a similar thing with SSH? I.e., if I am SSH'ed into a remote host, is it possible to set things up so that running code file.txt will open VS Code on my local machine, connected via the remote SSH extension to open that file?

jediahkatz
  • 231
  • 1
  • 2
  • 5
  • Might not be exactly what you're looking for, but there's a Visual Studio Code extension that allow you edit files from a remote server inside Visual Studio Code locally. https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh – Jonathan Wang Jun 07 '20 at 01:59
  • 2
    Does this answer your question? [Vscode (code.exe) command line arguments to immediately open a remote workspace folder over SSH](https://stackoverflow.com/questions/64710228/vscode-code-exe-command-line-arguments-to-immediately-open-a-remote-workspace) – Jacob Stern Apr 13 '21 at 15:16

6 Answers6

17

I found much better & simple answer thanks to this post.

Simply create new script file named code with below contents & put file under any folder from $PATH. (echo $PATH to see what folders you can use)

#! /usr/bin/env zsh

local max_retry=10

for i in {1..$max_retry}
do
    local script=$(echo ~/.vscode-server/bin/*/bin/remote-cli/code(*oc[$i]N))
    if [[ -z ${script} ]]
    then
        echo "VSCode remote script not found"
        exit 1
    fi
    local socket=$(echo /run/user/$UID/vscode-ipc-*.sock(=oc[$i]N))
    if [[ -z ${socket} ]]
    then
        echo "VSCode IPC socket not found"
        exit 1
    fi
    export VSCODE_IPC_HOOK_CLI=${socket}
    ${script} $@ > /dev/null 2>&1
    if [ "$?" -eq "0" ]; then
        exit 0
    fi
done

echo "Failed to find valid VS Code window"

Bash version

#! /bin/bash
                                                                             
max_retry=10                                                                 
                                                                             
for i in $(seq 1 $max_retry)                                                 
do                                                                           
    recent_folder=$(ls ~/.vscode-server/bin/ -t | head -n$i | tail -1)       
    script=$(echo ~/.vscode-server/bin/$recent_folder/bin/remote-cli/code)   
    if [[ -z ${script} ]]                                                    
    then                                                                     
        echo "VSCode remote script not found"                                
        exit 1                                                               
    fi                                                                       
    socket=$(ls /run/user/$UID/vscode-ipc-* -t | head -n$i | tail -1)        
    if [[ -z ${socket} ]]                                                    
    then                                                                     
        echo "VSCode IPC socket not found"                                   
        exit 1                                                               
    fi                                                                       
    export VSCODE_IPC_HOOK_CLI=${socket}                                     
    ${script} $@ 2>/dev/null                                                             
    if [ "$?" -eq "0" ]; then                                                
        exit 0                                                               
    fi                                                                       
done                                                                         
                                                                             
echo "Failed to find valid VS Code window"

Update

Above script doesn't work with recent updates. I had to change first line to

local script=$(echo ~/.vscode-server/bin/*/bin/remote-cli/code(*oc[1]N))

Update2

Original script may fail if recently opened ssh window is closed, yet there is another SSHed window open. I have enhanced the script to enable retrying the command with recent N(default 10) windows.

Lazy Ren
  • 704
  • 6
  • 17
  • 3
    Extremely useful! – ivallesp Feb 04 '22 at 11:39
  • Works like a charm! @jediahkatz tried it? Can be accepted as the best answer IMHO. Straightforward usage of bin will reply `Command is only available in WSL or inside a Visual Studio Code terminal.` Related question without answer https://www.reddit.com/r/vscode/comments/t4j7j4/open_vscode_from_itermssh_using_code/ – amordo Oct 10 '22 at 18:46
  • I keep getting - '/home/averma5/.vscode-server/bin/*/bin/remote-cli/code(*oc[1]N))': not a valid identifier – user5319825 Dec 20 '22 at 17:27
  • @user5319825 are you using zsh? AFAIK, this script only works for the zsh, it needs some tweaks to run the script under a different environment. – Lazy Ren Dec 21 '22 at 06:13
  • @LazyRen thanks for responding. No it's not zsh, I'm running that on bash, can u please help me here? – user5319825 Dec 21 '22 at 06:48
  • @user5319825 I've updated the bash version of the script. Please check if it works. But I cannot guarantee it... I'm not really familiar with the shell scripts. – Lazy Ren Dec 21 '22 at 08:20
  • I cannot find anything related to vscode under /run/user/$UID/. Am I missing anything? – Wei Qiu Feb 27 '23 at 11:25
  • 2
    On ubuntu linux 20.04, vscode-ipc-* seem to stay under /tmp. I need to change `/run/user/$UID` to `/tmp`. EDIT: It's quite strange. On another machine, vscode-ipc-* do show up under `/run/user/$UID`. – Wei Qiu Feb 27 '23 at 11:34
  • 1
    For WSL2 Ubuntu, the socket path is `/mnt/wslg/runtime-dir/vscode-ipc-*`. [Implementation example](https://github.com/planetsLightningArrester/run-commands/blob/2d7ed833d402b8da3697666e3538216ae4a7fe93/functions/code) – Francisco Gomes Jul 15 '23 at 16:39
  • For ubuntu22.04, the ipc sock is located in `/tmp`, it dose works for me. This is amazing, I thought it was stupid question unit I searched. – Jay Aug 29 '23 at 17:27
6

You shouldn't have to do anything. VSCode automatically sets the path/PATH to the code in the path/PATH environment variable depending on your shell. See this response. You might be overwriting your path/PATH like I was. I was accidentally overwriting path in ~/.cshrc and PATH in ~/.bashrc and was running into the same issue. After fixing it, I can run code on the command line. which code returns the location of the command.

Until I spent time to figure it out, I was using the two methods mentioned below. Both of which worked for me in bash; you can modify it for your shell as you see fit. But really fix your path/PATH rather than using these methods.

  1. Adding location of code to the PATH in ~/.bashrc

    export PATH=${VSCODE_GIT_ASKPASS_NODE%/*}/bin:$PATH

OR

  1. Setting alias to code in ~/.bashrc

    alias code="${VSCODE_GIT_ASKPASS_NODE%/*}/bin/code"


More on path vs. PATH here and here

Praveen Lobo
  • 6,956
  • 2
  • 28
  • 40
2

Yes, sort of. From a VSCode terminal run the command env | grep VSCODE_IPC_HOOK_CLI then copy-and-paste that line that line with export into your ssh terminal. After that, you should be able to run code from your ~/.vscode-server/bin/XXX/bin directory.

VSCode terminal

enter image description here

SSH terminal

enter image description here

Update:

You can to automate this with a .bashrc and .profile to place the IPC code into a temp file, and source that when you do your ssh login.

For example, this works for me...

Append this to ~/.bashrc

#
if [ "$VSCODE_IPC_HOOK_CLI" != "" ]; then
cat >$HOME/.vscode_env.sh <<EOF
#
if [ "\$VSCODE_IPC_HOOK_CLI" = "" ]; then
export VSCODE_IPC_HOOK_CLI="$VSCODE_IPC_HOOK_CLI"
alias code="${VSCODE_GIT_ASKPASS_NODE%/*}/bin/code"
fi
EOF
fi

And append this to your ~/.profile

[ -f $HOME/.vscode_env.sh ] && . $HOME/.vscode_env.sh

(There may be more elegant ways. And you still have to start at least 1 terminal in your remote VSCode session.)

Daniel
  • 137
  • 1
  • 4
  • Does the VSCODE_IPC_HOOK_CLI change? I need to add the 'env|grep' in bashrc? And should I alias this .vscode-server code? – Fred Guth Apr 30 '21 at 14:22
0

this works to me

if [[ -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]; then
  local script=$(echo ~/.vscode-server/bin/*/bin/remote-cli/code(*oc[1]N))
  if [[ -z ${script} ]]
  then
      echo "VSCode remote script not found"
      exit 1
  fi
  local socket=$(echo /run/user/$UID/vscode-ipc-*.sock(=oc[1]N))
  if [[ -z ${socket} ]]
  then
      echo "VSCode IPC socket not found"
      exit 1
  fi
  export VSCODE_IPC_HOOK_CLI=${socket}
  alias code=${script}
fi
David
  • 31
  • 3
0

Lazy Ren's script for bash almost worked for me. However it was giving an error in the retry strategy.

The following is working for me:

#! /bin/bash
                                                                             
max_retry=10                                                                 
                                                                             
for i in $(seq 1 $max_retry)                                                 
do                                                                           
    recent_folder=$(ls ~/.vscode-server/bin/ -t | head -n$i | tail -1)       
    script=$(echo ~/.vscode-server/bin/$recent_folder/bin/remote-cli/code)   
    if [[ -z ${script} ]]                                                    
    then                                                                     
        echo "VSCode remote script not found"                                
        exit 1                                                               
    fi                                                                       
    socket=$(ls /run/user/$UID/vscode-ipc-* -t | head -n$i | tail -1)        
    if [[ -z ${socket} ]]                                                    
    then                                                                     
        echo "VSCode IPC socket not found"                                   
        exit 1                                                               
    fi                                                                       
    export VSCODE_IPC_HOOK_CLI=${socket}                                     
    ${script} $@ 2>/dev/null                                                             
    if [ "$?" -eq "0" ]; then                                                
        exit 0                                                               
    fi                                                                       
done                                                                         
                                                                             
echo "Failed to find valid VS Code window"

On line 7 and 14, when i is greater than 1, recent_folder and socket become a list, and the rest of the script does not work.

To solve, I have added a | tail -1 to line 7. The combination of |head -n$i | tail -1 should give the 'ith' line, which is what we want.

-1

Use the below commands to open a folder or a file on the remote terminal. Note: vscode-server must be already installed on the remote host (It would be, if you have already connected to it). Also the absolute path has to be specified for the file or folder. Use -n to launch in new window,-r to reuse same window.

code --folder-uri <absolute-path>
code --file-uri <absolute-path-file-name>

Example:

code -r --folder-uri /home/myscripts/src           
code -n --file-uri /home/myscripts/src/math/sample.py
Bharath
  • 358
  • 2
  • 9