Learn › Linux Foundations › Multiplexers
Final test: Chapter 18, Multiplexers. Twenty-five objectives on a real Debian 12 server: tmux -V and tmux ls, a detached session started with new-session -d -s and listed, commands handed in with send-keys and read back from the files they wrote, a line staged without Enter and finished with the Enter key alone, an attach and the Ctrl-b d chord, an endless job left running inside a session, a second session ordered by name and ended with kill-session, then screen -dmS, screen -ls, screen -r with the Ctrl-a d chord, and screen -X quit. Fifty minutes, graded from the commands you run, the files your sessions write, and the session list your shell records.
This chapter covers the following topics:
What you already know: Chapter 9 started a job in the background with an ampersand and used nohup to let one program survive the end of a session. Chapter 11 sent output to a file with the greater-than sign. This chapter keeps a whole shell alive instead of one program, and hands commands to it from outside.
Objectives
After this chapter you can:
Start the practice machine and use its Terminal beside this lesson. This is a real Debian machine. Your files, current directory and multiplexer sessions stay between steps while the machine is running. The shell prompt shows your account, host and current directory; its decoration may differ from the recorded examples.
Before starting an interactive exercise, read how to leave it. tmux detaches with Ctrl-b, release, then d. Screen detaches with Ctrl-a, release, then d. Detaching keeps work running; End session removes the lab machine and its files. A multiplexer cannot keep work alive after that machine is removed or rebooted.
Examples below are recorded output, not observations from your current machine. Dates, process IDs, paths in listing output and growing line counts can differ. The chapter assessment starts a separate fresh machine and checks its own objectives automatically. Use the workspace timer for the time remaining.
Five questions before the material. A wrong answer costs nothing: the explanation states the fact and names the section that teaches it.
>>> Closing a terminal normally causes a hangup, and the shell or its jobs may exit. The details depend on the shell, program and service policy. Chapter 9's nohup is one exception. Section 18.2 introduces a separate terminal on the server that you can reconnect to.
>>> tmux runs a server process on the machine, and every session belongs to that process. Your terminal is only a client that draws it. Section 18.2.
>>> send-keys types characters into a session as if a person had typed them. Nothing runs until the Enter key arrives, because that is what running a line means at a prompt. Sections 18.4 and 18.5.
>>> Detaching disconnects your terminal from the session and changes nothing inside it. The shell in there never notices. Section 18.6.
>>> screen is the older tool and tmux the newer one. Both hold sessions on the server; the subcommands differ, and so does the key that starts a chord. Section 18.8.
This chapter works in one directory of its own, ~/sessions. It holds two small programs written for the chapter and one empty directory that the work you send into a session writes into.
Stand in it first: change to ~/sessions.
prompt: admin@server1:~$ answer: cd ~/sessions ||| cd sessions ||| cd /home/admin/sessions output: hint: Section 18.1. The directory-changing command from Chapter 2, then the path ~/sessions.
Nothing is printed, and the prompt now ends in ~/sessions. Chapter 2 established that: cd says nothing when it works.
You are standing in ~/sessions after Exercise 18-1. A long listing shows the two programs and the directory their results land in.
prompt: admin@server1:~/sessions$ answer: ls -l ||| ls -l . ||| ls -l ~/sessions output: total 12 drwxr-xr-x 2 admin admin 4096 Jan 15 2026 evidence -rwxr-xr-x 1 admin admin 385 Jan 15 2026 import-run -rwxr-xr-x 1 admin admin 413 Jan 15 2026 queue-watch hint: Section 18.1. The listing command from Chapter 2 with the option -l, on its own from ~/sessions or with the path ~/sessions after it.
Three entries. evidence is a directory, empty for now: every command this chapter hands into a session writes its result in there, and you read those files from outside. The x letters in the permission column say the other two are executable, files the system will run as programs.
import-run takes about nine seconds and prints three lines. queue-watch runs until you stop it. Between them they cover the two cases a session is for: work that finishes while you are away, and work that must keep going.
A program you are about to hand to a session is worth reading first. cat prints it, because a program written in shell is an ordinary text file. Read ~/sessions/import-run.
prompt: admin@server1:~/sessions$ answer: cat import-run ||| cat ./import-run ||| cat ~/sessions/import-run output: #!/bin/bash
#
sleep 3 echo "import-run: reading $HOME/logs/access.log" sleep 3 echo "import-run: $(wc -l < "$HOME/logs/access.log") lines imported" sleep 3 echo "import-run: done" hint: Section 18.1. The reading command from Chapter 5, then import-run, or ~/sessions/import-run from anywhere.
Three sleep commands and three echo commands. sleep 3 does nothing for three seconds, which is how this program takes long enough to be worth walking away from. The counting in the middle is wc -l from Chapter 5, reading the web server log Chapter 2 put in ~/logs.
The program prints to the screen. It writes no file of its own, so where its output ends up is decided by whoever runs it. Section 18.4 decides that with the redirect from Chapter 11.
Suppose a report takes several minutes. You want to close your connection and return to the same shell later, with the report still running. A terminal multiplexer keeps a terminal on the server and lets your connection attach to it.
tmux has two parts. The client displays the terminal you are looking at. The server is a separate process on the lab machine that manages its sessions. Disconnecting the client does not end the server or the work inside it.
A session groups windows; a window contains one or more panes. Each pane has a terminal that runs a shell or another program. This chapter uses one window and one shell per session, so you can first learn which work belongs where.
Without a multiplexer, closing a terminal can send a hangup to the shell or its jobs. Chapter 9 used nohup for a single program. tmux also gives you a terminal to return to, including its working directory, command history and running foreground program. It does not protect against a reboot, the lab timer ending, or a program failing.
GNU Screen provides a similar way to detach and resume terminals. Learn the tmux workflow first; later you will compare Screen's different commands and prefix key.
Ask tmux which version is installed. -V uses a capital V. Consult that version's manual when an option is unfamiliar.
prompt: admin@server1:~/sessions$ answer: tmux -V output: tmux 3.3a hint: Section 18.2. The program name and the version option -V, a capital letter, with nothing else on the line.
The name and the version, on one line. This machine has tmux 3.3a, the build Debian 12 ships. Version numbers matter here more than usual. The subcommands in this chapter are old and stable, but tmux gained many of its options over the years. A manual page written for a different version can describe an option this one does not have.
History. Screen was first released in 1987 and later became a GNU project. tmux was first released in 2007 and entered OpenBSD's base system in 2009. Both were written for the same problem: a connection that drops while work is still running on the other end.
tmux ls lists the sessions. Run it now, before you have started anything, because the refusal teaches the architecture.
prompt: admin@server1:~/sessions$ answer: tmux ls output: error connecting to /tmp/tmux-1000/default (No such file or directory) hint: Section 18.2. The program name and the two-letter listing subcommand ls, run before any session exists.
This is not a complaint about your typing. Read what it says: tmux tried to connect to /tmp/tmux-1000/default and there is no such file.
That file is a socket, a file that two programs use to talk to each other. It is how the tmux command you just typed reaches the tmux server, the background program that owns every session. 1000 in the path is your account's user id, so each account gets its own socket and its own server.
There is no socket because no server is running, and no server is running because you have no sessions. An empty list is not a thing tmux stores: with nothing to hold, the server does not exist at all. Section 18.9 watches it disappear again.
tmux new-session starts a session. Two options make it the form a server administrator uses:
-d starts it detached, which means the session runs but your terminal is not connected to it. Without -d, tmux would take your screen over immediately.-s gives the session a name. Without a name, tmux numbers it 0, 1, 2, and a number is a poor way to remember what a session is for.Start a detached session called work.
prompt: admin@server1:~/sessions$ answer: tmux new-session -d -s work ||| tmux new -d -s work output: hint: Section 18.3. The subcommand that makes a session, the option -d, the option -s, then the name work.
On success, this command normally prints nothing. That alone is not proof that the session exists. The next step lists sessions so you can verify that work was created.
The shell inside work is a real interactive shell, the same kind you are typing in. It has a current directory of its own, which is the directory YOU were standing in when you started the session, ~/sessions if you followed Exercise 18-1. It also reads its startup files before it can accept anything. That last point matters in the next section.
tmux ls is short for tmux list-sessions. Both spellings do exactly the same thing, and you will meet both in other people's notes. Use the long one here.
prompt: admin@server1:~/sessions$ answer: tmux list-sessions output: work: 1 windows (created Thu Oct 1 05:26:29 2026) hint: Section 18.3. The program name and the long spelling of the listing subcommand, list-sessions.
One row, one session. The row reads: the name you gave it, how many windows it holds, and when it was created. Your created stamp is the moment you started the session, so the date and time differ from the one printed here.
A window is a screen inside a session, and a session can hold several. This chapter uses one window per session and never opens a second, because one is enough to carry every idea in the chapter.
The same command refused a moment ago. Now there is a server to answer it.
The session is running and you are not in it. You do not have to go in to give it work: tmux send-keys types characters into a session as if a person were sitting at it.
After the subcommand, the line has three parts:
-t work says which session the keys are for. -t is short for target.'hostname > ~/sessions/evidence/host.txt' is the line to type, wrapped in single quotes so your own shell hands it over whole instead of running it.Enter is the name of a key, not a word to type. Without it the line is typed and left sitting there, which is the point of Section 18.5.The command inside the quotes is the redirect from Chapter 11: run hostname, and put its output in a file instead of on the screen. The path in it starts at the tilde for a reason. The shell inside the session has a working directory of its own. It is wherever YOU were standing when you started that session, so a relative path would be read against the session and not against you.
The new session's shell needs to reach its prompt before it can receive keys. tmux send-keys can return without an error even if those keys arrived too early. On the real server, tmux attach -t work opens the work session. Wait until its shell prompt appears. To return to your own prompt without ending the session, hold Ctrl and press b, release both keys, then press d. Now send the line below and read the evidence file in the next step. If the file is absent, attach once to inspect the prompt, detach, and retry that exact send once. If it is still absent, stop and inspect the command and session rather than sending it repeatedly. Make the same prompt check for the later report session. A silent send is not proof that work ran.
prompt: admin@server1:~/sessions$ answer: tmux send-keys -t work 'hostname > ~/sessions/evidence/host.txt' Enter output: hint: Section 18.4. The sending subcommand, the target -t work, the redirect into ~/sessions/evidence/host.txt in single quotes, then the name of the key that runs it.
A successful send normally prints nothing in the outer terminal. It shows that tmux accepted the keys, not that the shell finished the requested work. Read the file in the next step to verify the result. If the file is absent, inspect the session before retrying.
The file is ~/sessions/evidence/host.txt, under your own home directory, so you read it the ordinary way. Nothing about it is special.
prompt: admin@server1:~/sessions$ answer: cat evidence/host.txt ||| cat ~/sessions/evidence/host.txt ||| cat /home/admin/sessions/evidence/host.txt output: server1 hint: Section 18.4. The reading command from Chapter 5, then evidence/host.txt, or ~/sessions/evidence/host.txt from anywhere.
The machine's own name, written by a shell you never typed into. You did not run hostname. The session ran it, and the file is the evidence that it did.
The same shape carries a job that takes time. import-run needs about nine seconds, and while it runs inside the session your prompt out here stays free.
The path is written in full inside the quotes, because the session has its own current directory and you should not have to remember what it is. Send ~/sessions/import-run in, with its output redirected into ~/sessions/evidence/import.log.
prompt: admin@server1:~/sessions$ answer: tmux send-keys -t work '~/sessions/import-run > ~/sessions/evidence/import.log' Enter output: hint: Section 18.4. The same sending shape at -t work, with ~/sessions/import-run and a redirect into ~/sessions/evidence/import.log inside the quotes, then the key that runs it.
Silence again, and the prompt is yours immediately. The nine seconds are being spent in there, not out here.
This is the difference between a multiplexer and the ampersand from Chapter 9. A background job started with & still belongs to your shell's job table. Losing the connection can end it; & by itself does not provide a session to reconnect to. This job runs in a separate tmux shell that stays alive when your browser connection drops.
The program contains a nine-second wait. Allow it to finish, then read ~/sessions/evidence/import.log. Scheduling can add time. If the final import-run: done line is absent, wait and read the file again; do not start a second copy of the job just because the first is still working.
prompt: admin@server1:~/sessions$ answer: cat evidence/import.log ||| cat ~/sessions/evidence/import.log output: import-run: reading /home/admin/logs/access.log import-run: 10000 lines imported import-run: done hint: Section 18.4. The reading command from Chapter 5, then evidence/import.log, or ~/sessions/evidence/import.log from anywhere.
Three lines, the same three every time: the file it read, the count it found, and the word that says it finished. The count comes from ~/logs/access.log, which holds 10000 lines on every one of these machines.
Nothing was attached to that session while any of this happened.
wc -l from Chapter 5 counts the lines of that same file, ~/sessions/evidence/import.log.
prompt: ad
Practice Chapter 18. Multiplexers: tmux and screen in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.