Don't Fear the Headless Machine
A beginner's guide to working on a remote computer.
This getting-started guide teaches you about working with remote computers without a graphical user interface, so-called “headless” machines. As I have to explain these things to others rather frequently, I just consolidated them here. You will see that it is actually rather simple and once set up, you will have very powerful new tools at your disposal. Below you will find the answers to:
- How to “get in” to the remote computer?
- How to move files between your computer and the remote computer?
- How to edit a file on the remote computer?
- How to persist your session, e.g., for long running commands?
- And also some further useful tricks
The guide assumes the remote computer is running Linux and you know what a terminal is and how to execute commands on it. I also assume that you have basic knowledge of what a file, directory, and a path are. Your local computer should run Linux. On Windows, you may use the Windows Subsystem for Linux to get a virtual Linux environment. On Mac OS many of the commands below may just work.
Introduction and Setup
To start working, you require the IP Address or URL of the remote computer you want to connect to. Also, you should possess credentials (username and password) of an account on the remote computer (that is allowed to log in on the remote computer via SSH). You can get these from the administrator of the remote computer.
If this is you or the remote computer is one of your own computers, you probably already have a username and password.
What you need to do in addition is (1) install an SSH server, such as the one provided by OpenSSH and enable it to allow your user account to log in and (2) make sure the computer is reachable from within the network you are trying to connect from.
I will not go into detail on this here.
The Terminal
We start with some basic concepts of the terminal.
If you are on Linux, just open a new Terminal window.
On modern Windows operating systems, you can install the “Windows Subsystem for Linux”, install a Linux distribution (e.g., Ubuntu), and then just type bash into the PowerShell to enter a virtual Linux environment.
You can now just start typing a command.
Commands consist of the name of a program and some optional or required arguments.
Optional arguments typically start with a dash, e.g., -i or two dashes when they are longer than one character, e.g., --help.
To execute a command, hit Return/the enter key.
For example, ls will list the files in your current directory.
With cd some/path/to/a/folder you can navigate to a different directory.
cd .. will move you one level up in the file tree.
With mkdir name, you can create a new folder called name; with mkdir -p name/and/more/folders you can create a complete path of folders in one go.
If you want to interrupt a running command, type Ctrl+C.
exit will close the terminal.
When you typed commands, you can use the up and down arrow keys to scroll through your history.
Most of the time, it is not possible to just place the cursor inside a command using the mouse to edit it.
Use the left and right arrow keys or keyboard shortcuts, such as Ctrl+left arrow or Ctrl+E instead.
While typing, you can press Tab to get options for automatic completion: the shell will guess what you may have meant and display your options.
The text printed automatically by your terminal in front of every command is called a prompt.
It tells you, depending on the configuration, which folder you are in (just like the pwd print-working-directory command), the name of the computer you are on (just like the uname -n command), and also the user you are logged in as (just like the whoami command).
SSH
Now that you have basic familiarity with the command line, you are ready to connect to the remote computer.
The secure shell protocol (SSH) is your way to log in to a terminal on your remote computer. Most Linux systems come with OpenSSH installed already.
To connect to your remote computer via SSH, type ssh <username>@<address>, replacing <username> with your username on the remote computer and <address> with the remote computer’s IP address or URL1.
For example, ssh justinnk@192.168.0.42.
You should be prompted for your password.
Type it in and hit Return.
Most of the time, the prompt is going to change: On your local computer, it should read something like <username>@<your PC's name>, whereas on the remote computer, it should read <username>@<remote computer's name>.
However, this depends on the default shell of the remote computer and you may not see this change.
In this case, you can use the command uname -n to see whether you are indeed now logged in to the remote computer.
It will tell you the name of the current computer.
And this is it, you are practically ready to start executing commands on the remote computer’s terminal.
However, there are a couple of further things you can do to make (re-)connecting much more convenient.
To follow the below instructions, log out of the remote terminal by executing the command exit.
SSH Keys
Instead of typing in your username and password all the time, you can use a so-called SSH key, or rather, a pair of keys. It comprises a secret, private key on your computer and a public key you can copy to any other place. Possession of the private key is used to prove your identity and it should thus be kept secret at all costs (you can also protect it with a passphrase). Using this, you can generate a key pair and copy your public key to the remote computer. Your computer then uses the private key on your local computer to prove to the server that you are indeed you. This eliminates the need to remember different credentials for all of your remote computers. Together with the information provided in the next section, you can also avoid re-typing your username and password upon every connection.
To generate such a key pair, run ssh-keygen and follow the instructions on the screen.
If you are uncertain at any point, just accept the default for now by hitting Return.
This is also where you can enter a passphrase to protect your private key, in case someone steals it from your PC.
If you don’t, this would directly give them access to all your remote computers!
After generating the key, you can run ssh-copy-id <username>@<remote computer's address> to copy your public key to the remote server.
This program will ask you for your account password one last time.
Log out of the remote server again, there is one more step before you can use your key to log in.
SSH Configuration
You need to configure your SSH client (the ssh program running on your local computer) to use the key when logging in.
While you are at it, you can also configure additional options to make your experience even more convenient.
The configuration files for your OpenSSH client are located in your home directory at ~/.ssh (or /home/<username>/.ssh) by default.
This is also where your SSH keys will be stored by default.
If there already is a file called ~/.ssh/config, open it in your favourite text editor.
Otherwise, create a new file at this path and open it.
Append to the file the following entry:
Host <name>
HostName <remote computer's address>
User <username on remote computer>
IdentityFile ~/.ssh/<name of your key>
Here, <name> can be anything you want.
This will be what you need to type in order to connect to your remote computer in the future, so an abbreviation of some kind or just its hostname are good choices.
The default keyname is something like id_ed25519 (or id_rsa on older systems), so the IdentityFile line would read IdentityFile ~/.ssh/id_ed25519 if you accepted the defaults when running ssh-keygen.
If you are unsure, look into the ~/.ssh/ directory and see what your key file is called.
Other useful configuration options that you can research yourself include:
Port: If your SSH server does not listen on the default port (22).AddKeysToAgentandForwardAgent: If your key is protected by a passphrase, you still have to type something on every connection attempt. An SSH agent will cache your decrypted private key for a limited amount of time.ForwardAgent yeswill forward your local private keys to be used on the remote server;AddKeysToAgentat the very top of your configuration file will enable adding the decrypted private keys to the SSH agent, so you only have to type the passphrase one time during a session.ForwardX11: this allows you to open GUI windows that originate from the server on your local computer. However, your local computer has to run the X11 windowing system and the server should haveX11installed for this to work.ProxyJump: this is useful to access remote computers behind a bastion host or firewall by first connecting to the proxy node.
Once you are done, save the file.
You can now just type ssh <name> to connect to your remote computer.
Note, if you are asked for a password, it is the passphrase you specified for your SSH key and not the one matching your username.
If you frequently connect and disconnect from remote computers, using an SSH agent like described above will eliminate the prompt for the passphrase after you first typed it in during a session.
You can find more information on this elsewhere on the internet.
Copy files from and to the remote computer
There are several options to copy files between your local and the remote computer.
The one I use the most is the program (command) rsync <source> <destination>.
By specifying the destination as <user>@<remote computer's address>:/path/to/file/on/remote (or if you followed the configuration guide above shortened to <name>:/path/to/file/on/remote) and the source as a path on your local computer, you can copy files to the remote computer.
For example, rsync ~/my_file.txt justinnk@192.168.0.42:/home/justinnk/ will copy my_file.txt to the home folder on the remote computer.
If you configured SSH to use an abbreviation for the remote computer’s address, let’s say turing, you can use it here as well: rsync ~/my_file.txt turing:/home/justinnk/.
Likewise, specifying the source in an analogous manner and the destination as a path on your local computer will copy files from the remote computer to your computer.
Note that rsync will overwrite the files at the destination by default, hence the “sync” in the name.
I recommend running these commands on your local computer, where you have the nice SSH configuration. While running them on the remote computer (with the paths swapped, of course) is possible, this requires your local computer to run an SSH server for the remote computer to access your local computer via SSH.
The rsync command accepts several options, such as compression for large files during transit (-z).
There is also the option to simulate what would happen without making changes using --dry-run.
The -v (verbose) option gives you some more information on what is happening.
I often run rsync -avz, where the additional a enables recursion (syncing directories), preserves symlinks, file owners, etc.
See man rsync for more information.
Remote text editing
Of course you can copy files from and to the remote computer all the time.
However, there will come a time when it would be convenient to just edit something on the remote location directly.
Without a graphical user interface, you need to resort to command line text editors.
Again, there are several options.
I personally recommend you learn the basics of vim, although that is only my opinion.
Other options include nano and emacs.
However, vim or its predecessor vi tend to be preinstalled on many systems.
Vim has many powerful keybindings, which allow you to perform any editing action you can imagine with ease in no time (once you get used to the basics).
If you open vim (by mistake), you can quit by typing :q!.
For the time being, you might want to resort to nano.
It is often pre-installed and will provide you some important shortcuts directly on-screen.
To edit a file, type nano path/to/file.
If you want to create a new file, note that path/to/file can also be non-existent.
In this case, nano will create it with your typed in content upon saving.
Keep in mind, however, that the directories path/to have to exist (you can use mkdir or mkdir -p for this).
Vim
Here are some quickstart instructions for Vim.
To start learning Vim, type vimtutor (may need to be installed first).
The basics are as follows.
Type i to enter insert mode.
You can now type text as you wish.
To get back to normal mode, hit Esc.
You can move the cursor in normal mode with h (left), j (down), k (up), and l (right) or the arrow keys.
However, the latter are less ergonomic.
To save the file and exit, press : to enter command mode (see the line at the bottom of the screen), and type wq.
There are a lot of other movements in normal mode, such as w to skip over words, Ctrl+d and Ctrl+u to move down and up faster, gg/G (G is Shift+g) to move to the top/bottom of a file, or f followed by any letter to skip to the next occurrence of this letter.
What makes Vim and its shortcuts so powerful is that you can combine the commands and movements, so for example dw will delete one word and df, will delete everything between the cursor and the next comma on the same line.
Tmux
A final challenge you may encounter is to persist your session. You may have noticed that once you close the terminal, all the commands running in the foreground are terminated. Also, sometimes you may want to have multiple terminal sessions on the remote computer to work with.
A program providing a solution to both is the terminal multiplexer tmux.
A popular alternative is screen.
It will launch a separate process that will persist over logouts.
To start, just type tmux and you will be provided with a new shell and a status bar at the bottom of the screen.
First things first, to “detach” (exit tmux without terminating its background process), hit Ctrl+b and then d.
In fact, to interact with tmux, you have to press Ctrl+b first, which lets tmux know that the next command is meant for it and not the terminal.
When you want to resume, type tmux a to reattach to the most recent tmux session.
You can create a new terminal in a tmux session with Ctrl+b and then c.
To move between them, use Ctrl+b and n or p.
To quit the remote session, close all tmux windows, e.g., by typing exit in all of them.
This concludes our journey. I have provided you with the very basics to get you started. From here, feel free to explore for yourself what is possible! To conclude, here are some useful tricks.
Some useful Tips & Tricks
- You can use
man <command>to get information on many built-in Linux commands. - A terminal can run different so-called shells. The most popular is probably the
bashshell. When specifying paths, you can use wildcards, for example*.txt. In a process called “globbing”, this will expand to a list of files that end in.txtin the current directory. Many other shells support this feature too. - If your remote computer’s terminal seems weird and does not allow you to auto-complete, you can try typing
bashto start a bash shell. You then have to executeexittwo times to disconnect from the remote computer. grepis a very powerful tool, in particular when used asgrep -r "search" .. The latter will find any occurrence of the word “search” in any file in the current directory and its subdirectories. With-A2(-B2) you can also get the two lines after (before) the match for additional context. I usegrepalmost daily and it is no wonder it is very popular with large language model AI agents.- You can use the
htopcommand to see the CPU and memory usage of the remove computer. - You can use
lscputo see exactly what your remote computer is made up of. - Prepending
time(followed by a space) to any command will tell you how long it took at the end. - If you run a long-running command, write its output to a file for later reference:
myprogram 2>&1 | tee log-file.txt. Theteecommand will write to the file and your terminal. The|is called a “pipe” (you can search for it on the internet). It is used to stream the output of one command to another. The2>&1will combine the errors and normal output of the command (they are usually separated on two different output streams,stdoutandstderr). Alternatively, you can also use thescriptcommand to record entire terminal sessions. - If you ever need to mass-edit files, have a look at
sed, the stream editor. For example, to find and replacefoowithbarin all text files in the current directory, you can runsed -i.bak "s/foo/bar/g" *.txt. However, use it with caution! This will change all the files in the current directory! The.bakafter the-iargument is a postfix used for creating backups of the original files. So you can find the original version of a file namedone.txtunderone.txt.bakin case you want to roll back the changes. Seeman sedfor more details. - There are some differences when using
Mac OSorBSDinstead of theGNUversions of the commands assumed above. For example, withsed, the syntax changes tosed -i '.bak' "s/foo/bar/g" *.txt.
-
If the SSH server on the remote computer is configured to listen on a non-default port (not 22), then you can use
-p <port>to set the right port. ↩︎

