Edit on the server: nano, vi or vim
ssh -t user@server nano /etc/nginx/sites-available/site.conf
ssh -t user@server vi /etc/nginx/sites-available/site.conf
The editor runs on the server and you see it through the session. -t asks for a terminal, which an editor needs when you pass it as a command. Without it you get Pseudo-terminal will not be allocated. Minimal images often have no nano, while vi is nearly always present.
For a file owned by root, use sudoedit rather than sudo nano:
ssh -t user@server sudoedit /etc/demo.conf
ssh -t user@server SUDO_EDITOR=nano sudoedit /etc/demo.conf
sudoedit copies the file, opens the copy in your editor running as you, and writes it back as root when you quit. Your editor and its plugins never run as root, and the file kept its owner and mode in our test:
-rw-r--r-- 1 root root 4 Nov 6 15:27 /etc/demo.conf
Use a local editor: scp down and back up
To edit with the editor you have on your own machine, copy the file down, edit it and copy it back:
scp user@server:/etc/nginx/sites-available/site.conf .
cp site.conf site.conf.orig
# edit site.conf in your editor, then:
ssh user@server cat /etc/nginx/sites-available/site.conf | diff -q site.conf.orig -
scp site.conf user@server:/etc/nginx/sites-available/site.conf
The diff line guards against the usual accident: someone else changed the file on the server while you were editing, and your upload wipes their change. No output means the server copy is still the one you downloaded.
scp writes as your user, so a root-owned file fails:
scp: dest open "/etc/demo.conf": Permission denied
scp: failed to upload file demo.conf to /etc/demo.conf
Upload to /tmp and move it into place with sudo install, which also sets the mode:
scp demo.conf user@server:/tmp/demo.conf
ssh -t user@server sudo install -m 644 /tmp/demo.conf /etc/demo.conf
More forms of the command, with ports, keys and folders, are in scp examples.
Let vim do the round trip
vim scp://user@server//etc/nginx/sites-available/site.conf
vim scp://user@server/notes.txt
Vim's netrw plugin downloads the file to a temporary copy, and :w uploads it again with scp. Two slashes after the host mean an absolute path. One slash means a path inside your home folder on the server. It uses your keys and ~/.ssh/config, so a Host name and a jump host work too. In our test, a write through a jump host reached the server at once.
Emacs does the same with TRAMP: open /ssh:user@server:/etc/hosts with C-x C-f, and saving writes to the server.
Mount the folder with sshfs
sshfs user@server:/var/www ~/mnt/server
Every editor and tool on your machine then sees the remote folder as a local one. This suits a project with many files better than copying them one by one. Setup, unmounting and what to do when the connection drops are in mount a remote folder with sshfs.
Editors with a remote mode
Several code editors can work on a server over SSH. They copy a small helper program into your home folder on the server and run it as your user, so search, completion and the terminal run there while the window stays on your machine. This is the most comfortable option for long sessions on one project. It needs some disk space on the server and an operating system the helper supports, and the helper runs with all the rights of your account.
Before you save a config file
- Test before you reload. Run
sudo nginx -t,sudo sshd -torsudo visudo -c, depending on the file. A typo in a reloaded config can take a service down. - Keep a second session open when you edit
sshd_config, firewall rules or PAM files, so a mistake does not lock you out. - Watch line endings. A file saved with Windows line endings breaks shell scripts with errors such as
/bin/bash^M: bad interpreter. - Keep a copy.
sudo cp file file.bakbefore you start makes going back a single command.
Questions
How do I edit a root-owned file over SSH?
Run ssh -t user@server sudoedit /etc/file. sudoedit copies the file, opens the copy in your editor as your own user and writes it back as root when you quit. Choose the editor with SUDO_EDITOR=nano.
Why does nano say command not found on the server?
Minimal server images often ship without nano. vi is nearly always there, or install nano with the package manager, for example sudo apt install nano.
Can I edit a remote file with a local editor without copying it?
Not really: something always copies it. sshfs, vim scp:// and editors with a remote mode just do the copying for you, each time you open and save.
Why does my editor complain about the terminal over SSH?
You ran ssh server nano file without -t, so no terminal was allocated. Add -t: ssh -t server nano file.
Sources
- scp(1), OpenBSD manual
- sudoedit, sudo manual
- Vim netrw, pi_netrw.txt
- SSHFS README
- TRAMP manual, GNU Emacs