160

I have to edit some files placed on some server I could reach via ssh.

I would prefer to edit these files in customized vim on my workstation (I have not rights to change vim settings on remote server). Sometimes I would like to edit a file with sublime text or other GUI editor.

Of course, I can download these files, edit them locally and upload them back to server. Is there more elegant solution?

Loom
  • 3,953

9 Answers9

189

You can do that via scp like this:

vim scp://user@myserver[:port]//path/to/file.txt

Notice the two slashes // between server and path, which is needed to correctly resolve the absolute path. (The first slash is syntactic, while the second slash specifies the remote user's root directory, as usual. To start at the home directory, you'd do [:port]/~/path/to/file.txt.) [:port]is optional.

This is handled by vim's netrw.vim standard plugin. Several other protocols are supported.

llf
  • 103
FloHimself
  • 11,492
  • when you save the file changes are the saved back to the remote server? – rob May 12 '15 at 09:15
  • 8
    Yes, the file is retrieved to a temporary file, that is uploaded to the server on save. – FloHimself May 12 '15 at 09:17
  • 1
    Thank you. However, I have got an error, when tried to save file: E382: Cannot write, 'buftype' option is set – Loom May 12 '15 at 09:17
  • 1
    @Loom, I had the same problem, because I omitted the double slash //. Perhaps you made the same mistake? – Benjamin B. May 12 '15 at 09:18
  • 2
    You can try :set buftype=""​ in vim. – FloHimself May 12 '15 at 09:20
  • How would one pass a non-standard port to scp in this case? And is there a name for using scp in this way? – WhiteHotLoveTiger May 12 '15 at 15:27
  • 1
    Does this work with any text editor or vim specifically handles the scp protocol? – Hoffmann May 12 '15 at 18:40
  • @WhiteHotLoveTiger, Hoffmann: I've updated the answer. – FloHimself May 12 '15 at 19:03
  • Can the same be done with sublime test? Eg subl scp://... – code ninja May 13 '15 at 12:37
  • 1
    How did I go so long without knowing that feature existed? Thank you, sir, thank you. – Edward Falk Jun 27 '16 at 17:55
  • 6
    Furthermore, vim will read ~/.ssh/config and resolve remote hosts with vim scp://[host]/path. – Jangari Apr 03 '18 at 04:05
  • 1
    @Jangari, are you suggesting that we dont need to provide the hostname if its configured in ~/.ssh/config? Can you provide any details of this configuration. – alpha_989 May 30 '18 at 18:22
  • 3
    Include an entry in your ssh config with an alias for the host, the hostname, the username and path to the identity file, and then you can open a file from vim directly using vim scp://[alias]/path. If the path is relative to your login home on the remote, you'll have one slash. If absolute in the filesystem, two: vim scp://host//etc/ssh/ssshd_config. – Jangari May 30 '18 at 21:31
  • 2
    Here is a blog post explaining how to format and use a local ssh config. – Jangari May 30 '18 at 21:36
  • 1
    @FloHimself, Thank you very much for your answer. This has been in general working very well. – alpha_989 Jun 12 '18 at 20:02
  • 1
    one of the sideeffects of doing the above is that the log file itself gets locked. So if the code is running and you want to inspect the log file, any logging statements may not be written into the log file. I know I can manually get the file over scp, and then read it in vim, but is there a way to use something like :r scp username@ip:/path/to/log_file to fetch the file and then read it, to prevent locking up the file? – alpha_989 Jun 12 '18 at 20:02
  • 1
    @alpha_989: The remote file isn't locked in any way. If you're opening a remote log file, vim uses a local copy of the file. You can use vim's r command to refresh the file and get the current version from the server. However, if you save the file in vim, it will be updated on the remote system and you loose all log entries written after last file retrieval. But maybe vim is just not the right tool to inspect remote log files anyway... – FloHimself Jun 13 '18 at 07:59
  • Yeah.. you are right.. when I do use the command, I do see that it shows that its editing a file in the /tmp directory. I am primarily using vim to check the log files quickly. Do you know of a better tool (in Unix-like systems) to inspect remote log files? – alpha_989 Jun 13 '18 at 17:39
  • 1
    @alpha_989: Assuming there is tail on the remote machine, why not just use ssh user@remotehost tail -n 20 -F /path/to/log/file – FloHimself Jun 14 '18 at 07:53
  • Thats a great idea. Seems like the -F option continuously updates the status of the file.. so I can view it as the file updates. The remote machine is a Windows machine.. I do have git-bash installed on the remote machine.. which probably has tail.. so I can probably provide the direct path to the tail executable.. Will try it out and report back.. – alpha_989 Jun 15 '18 at 19:44
  • @codeninja take a look on https://packagecontrol.io/packages/RemoteCpp – KcFnMi Aug 07 '18 at 19:17
  • 1
    How is this not the accepted answer. Seriously WTF?! – Sukima Nov 15 '18 at 14:50
  • 1
    How can I make it work when I have to supply a key file along with scp? – markroxor Jan 18 '19 at 02:24
  • 1
    I know it's asking for too much, but is there a way to, umh, do this from an active vim session like load the remote file in a buffer and open that in the current window? I am expecting something like :scp ... but that doesn't seem to exist. – stillanoob Apr 02 '19 at 10:59
  • 9
    @stillanoob: :e scp://... – FloHimself Apr 02 '19 at 11:06
  • 2
    If the file name contains spaces, make sure to double escape them. e.g., :e scp://user@myserver[:port]//path/to/file\\ with\\ spaces.txt – Big McLargeHuge Aug 29 '19 at 18:05
  • brilliant, thanks for this tidbit, more info here as well: https://vim.fandom.com/wiki/Editing_remote_files_via_scp_in_vim – kjones Sep 27 '19 at 03:11
  • if elevated privileges are neede, use rsync instead of scp: 1.) :let g:netrw_rsync_cmd='rsync --rsync-path="sudo rsync"' and 2.) :e rsync://myhost.net:/etc/apt/sources.list see https://unix.stackexchange.com/a/744137/161003 – MacMartin Apr 26 '23 at 15:22
104

You could do this by mounting the remote folder as a file-system using sshfs. To do this, first some pre-requisites:

#issue all these cmds on local machine
sudo apt-get install sshfs
sudo adduser <username> fuse #Not required for new Linux versions (including Ubuntu > 18.04)

Now, do the mounting process:

mkdir ~/remoteserv    
sshfs -o idmap=user <username>@<ipaddress>:/remotepath ~/remoteserv

After this, just go into the mounted folder and use your own local customized vim.

shivams
  • 4,565
  • 6
    Unsurprisingly, the installation step will fail on distributions that are not deb-based and hence don't have apt-get. (In which case, yum or zypper might be present.) They also require root on the local machine, whcih may or may not be available. (This is not to say it's a bad solution, but it comes with a big prerequisite.) – Ulrich Schwarz May 12 '15 at 11:26
  • 8
    Okay. Figured it out. All of this is done on the local machine. In the case of OS X one has to install osxfuse and sshfs. These can be installed with homebrew (brew install sshfs and brew cask install osxfuse , or from packages obtained from https://osxfuse.github.io/ – inspirednz Jun 26 '17 at 03:22
  • 1
    what the idea with this command? sudo adduser <username> fuse did you mean to add a user to a group or something? It fails because adding a user in ubuntu doesn't allow another 'fuse' argument, and also because of course the current user already exists. – TamaMcGlinn Feb 05 '21 at 14:21
  • 1
    @TamaMcGlinn: I think you don't need that command anymore for new Ubuntu versions. Simply skip that command and let me know if it worked. I will update the answer accordingly. – shivams Feb 05 '21 at 15:03
  • yes, skipping that worked on ubuntu Focal Fossa. I also changed the last command to just sshfs <username>@<ipaddress>:/remotepath ~/remoteserv without the idmap, because I couldn't figure out from the docs why you would need that generally. – TamaMcGlinn Feb 05 '21 at 15:23
7

Multiple options are usable, not just "scp"; see: https://www.vim.org/scripts/script.php?script_id=1075

I like using "rsync" more, because for me "diff" didn't work correctly with scp.

Example - start vim with the "/tmp/test"-file on different remote servers (hostname01.domain.my and hostname02.domain.my and ...), using bash-extension, vertically split:

vimdiff -O rsync://hostname{01,02,03}.domain.my:/tmp/test

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
MacMartin
  • 2,924
  • Note that {01,02,03} is from csh in the 70s, not bash. {01..03} itself from zsh in the 90s. – Stéphane Chazelas Apr 17 '23 at 13:46
  • @StéphaneChazelas I'm not exactly sure what you mean. If I execute echo thing{1,2,3} then it prints thing1 thing2 thing3 (at least for bash version 5.1, see man bash -> "Brace Expansion"). But I also like zsh – MacMartin Apr 18 '23 at 06:59
  • I wanted to clarify that the syntax was not bash-specific nor invented by bash contrary to what using bash-extension would imply. – Stéphane Chazelas Apr 18 '23 at 07:01
6

Depending on what you mean when you say you do not have the rights to edit the Vim settings, there may be a way of using Vim on the server in the way you want anyway. If you can't change your user .vimrc (because you're logging in as a shared user, for example) but you can still create files, create it as a file called, say, Loom.vimrc and then call Vim using the -u switch:

vim -u ~/Loom.vimrc file_to_edit

You can even then use an alias: alias vim='vim -u ~/Loom.vimrc' will allow you to use Vim in the usual way, and it'll still load your custom .vimrc file. This alias won't persist after you log out, so you don't need to worry about anyone else accidentally using your customised Vim.

2

Depending on how many files and what kind of files you are expecting to edit, this is maybe not exactly what you want to do here, but I think it's worth mentioning. If you have to edit files in a remote server, but want to use everything you have in your own working station, then you may want to start thinking of using some kind of Revision Control system in your machines. That way, you can modify your local copies in your own machine using your software of choice, commit the changes, and then just update the local copies in the destination machine. Besides editing the files with whatever software you feel comfortable with, you have the added value of having a history of changes related to each file, which is always good.

Here's a list of Revision Control Software, just in case.

jimm-cl
  • 1,128
  • Are you suggesting the usage of something like commiting the changes to git, pushing it to something like github, and pulling the changes from github to your local machine, to make change there? – alpha_989 May 30 '18 at 18:19
  • That is feasible for complex code changes.. but for simple code changes perhaps.. what @FloHimself or shivams mentioned is easier to implement.. – alpha_989 May 30 '18 at 18:20
1

To expand on Mr. Potts answer: You can also do the above, then put something like this in .bash_profile (or whatever your shell uses):

if [[ "$(who mom loves | awk ' { print $1 }' )" == "Loom" ]]; then 
         alias vim="vim -u ~/.Loom_vimrc"  
         fi  

where Loom is your original userID that you login in as.

If you're logging in as a shared account (and not an individual account then sudo su - ing, then may Von Neuman have mercy on your soul for you are lost.

I would have put this in a comment, but I couldn't get the code formatted at all.

Petro
  • 646
  • 4
  • 8
1

If you have a vim sessions running already use

:silent e scp://user@myserver[:port]//path/to/file.txt

The :silent in front will suppress the Press Enter to Continue message

and

e scp://user@myserver[:port]//path/to/file.txt is the Ex mode command to edit the remnote file.

Tested with BitVise SSHD running on Windows 10, and using VIM runing on Ubuntu 16.04

alpha_989
  • 443
  • Just a note that this suppresses the Press Enter to Continue for the initial loading, but not for any subsequent :w – Sparhawk Oct 09 '18 at 04:45
0

If you are more GUI-oriented and use one of the more newbie-friendly Linux distros like Ubuntu or Mint, this is another option and does not require any more installations.

You should have nemo as your default file manager. It may not be called "Nemo" on the menu, so go under Help > About of your file manager ("Files" app) to see.

In nemo, go to File > Connect to server, enter your remote machine's details (SSH's default port is 22), and then open the files just like any file on your local machine, with whatever editor you prefer. You can even close Nemo and continue working in your editor.

From the address bar, it seems to be using the sftp protcol.

Just be aware that if your remote host has an inactivity timeout for the SSH connection, this will also prevent you from saving changes in the editor after the timeout has dropped the connection...

frIT
  • 133
-1

I quite often use something like the following

for i in hosta hostb hostc
do
ssh -t vim xx.txt
done

so the trick is

ssh -t vim xx.txt
ferg
  • 43