Hollywood: Director's Cut. The hacking-movie terminal, in a container, fitted to your screen.
522
┌──────────────────────────────────────────────────┐
│ HOLLYWOOD: DIRECTOR'S CUT │
├─────────────┬─────────────┬──────────────────────┤
│ SCENE: ∞ │ TAKE: 1 │ ROLL: /dev/urandom │
├─────────────┴─────────────┴──────────────────────┤
│ DIRECTOR: you CAMERA: tmux │
└──────────────────────────────────────────────────┘
The terminal that makes you look like you are hacking the Gibson. Re-edited. No studio notes.
🎟️ Rated T for Terminal. Contains falling green letters and mild technobabble.
🦖 Bystanders will say: "It's a UNIX system, I know this!"
Hollywood fills your terminal with busy technobabble: htop here,
falling green letters there, a world map for good measure. Dustin Kirkland wrote the original. This is my re-edit of
it, in a container, with the things that bothered me fixed.

Thirty seconds of the Director's Cut.
docker run -it --rm mapitman/hollywood-directors-cut
The same image is also published as mapitman/hollywood, its old name, so old commands keep working.
It runs on Intel and AMD machines (linux/amd64) and on ARM machines, Apple Silicon included (linux/arm64). Docker
picks the right one for you.
🎬 Only four panes on a Mac? Docker on a Mac runs inside a virtual machine, and the pane count is capped at two per CPU that the machine has. Colima starts with 2 CPUs, so you get at most 4 panes. To give it more, run
colima stopand thencolima start --cpu 8. In Docker Desktop, change the CPU setting under Settings, then Resources. To see how many CPUs the container gets, rundocker run --rm debian:trixie-slim nproc.
To leave the theater, press <ctrl> - c until the panes stop spawning, then press <ctrl> - d to exit the
container. You can also stop it from another terminal with docker stop hollywood, if you started it with
--name hollywood.
When Hollywood exits, the entrypoint puts your terminal back: it shows the cursor, leaves the alternate screen and
turns off mouse reporting. That also happens after docker stop. It cannot happen after docker kill, because
Docker gives the container no time to clean up. If your cursor is missing after a docker kill, run reset (or
tput cnorm).
The original works. I wanted it to look better on a big screen and to stop doing a few annoying things, so I changed these:
btop widget. It shows the CPU, memory, network and processes, and it shrinks to just the CPU box
when its pane is small.The details are under "Behind the scenes", and my reasons are under "Director's commentary".
Hollywood opens a tmux session and fills it with panes. Each pane runs one widget, and each widget wraps an ordinary tool. There are 21 widgets. All of them play themselves.
| Widget | Shows |
|---|---|
apg | random passwords from /dev/urandom, colored with ccze |
atop | system and process monitor (needs 60 x 24) |
bat | random source files from /usr, syntax highlighted with batcat |
bmon | network bandwidth monitor (needs 48 x 26, or 141 x 18) |
btop | resource monitor with CPU, memory, network and process boxes (needs 60 x 8, see "The btop widget") |
cmatrix | falling green characters, as in The Matrix |
code | random C, C++, Java and Python files, highlighted with pygmentize |
errno | the list of error codes, in random order |
figlet | large ASCII words such as ACCESS GRANTED (needs 57 x 7) |
hexdump | hex dumps of programs in /usr/bin |
htop | interactive process viewer |
jp2a | wallpaper photos in 256 colors, drawn with half blocks (see "Wallpapers") |
logs | log files under /var/log |
man | random man pages |
map | a map of the world in 256 colors, drawn once with half blocks (see "Wallpapers") |
mplayer | a sound-wave video in true color, drawn with half-block characters (see "The mplayer widget") |
pv | a fake file-transfer progress bar |
speedometer | network throughput graph |
sshart | random ssh-keygen key art (needs 20 x 12) |
stat | file details for random paths under /sys and /dev |
tree | directory trees under /sys and /dev |
The Debian slim image removes man pages and documentation. The Dockerfile puts them back so the man and code
widgets have something to show.
Every setting is an environment variable, because even directors take notes.
| Setting | Environment variable | Default |
|---|---|---|
| Cells per pane (this sets the maximum pane count) | HOLLYWOOD_CELLS_PER_PANE | 1400 |
Pick a random pane count up to the maximum, at the start and at every rebuild (0 always uses the maximum) | HOLLYWOOD_RANDOM_PANES | 1 |
| Minimum seconds a pane keeps a widget (the maximum is 1.5 times this) | HOLLYWOOD_DELAY | 30 |
Seconds between layout rebuilds (0 turns the rebuild off) | HOLLYWOOD_REBUILD | 300 |
Playback speed of the mplayer widget (0.5 is calmer, 1 is normal speed) | HOLLYWOOD_MPLAYER_SPEED | 0.75 |
Crop filter for the mplayer widget (scale shows the whole video) | HOLLYWOOD_MPLAYER_FILTERS | crop=128:64:0:16 |
Seconds the jp2a widget shows each picture | HOLLYWOOD_IMAGE_SECONDS | 3 |
Milliseconds between updates of the btop widget (btop accepts 100 or more) | HOLLYWOOD_BTOP_UPDATE_MS | 100 |
docker run -it --rm -e HOLLYWOOD_CELLS_PER_PANE=1000 -e HOLLYWOOD_DELAY=60 mapitman/hollywood-directors-cut
The -s (panes) and -d (minimum seconds a pane keeps a widget) options override the computed values:
docker run -it --rm mapitman/hollywood-directors-cut -s 6 -d 60
To find your terminal size, run stty size. It prints rows, then columns.
How the movie gets made.
The entrypoint script measures your terminal. Docker passes the size in character cells, so the script divides the
cell count by 1400 to get the maximum number of panes. Two other limits apply: two panes per CPU, and the number of
widgets. Then pane-count.sh picks a random number from 2 up to that maximum. Some layouts end up with fewer and
larger panes, and that is when the widgets that need a big pane can run. A full-screen terminal on a 1920x1080 screen
is about 161x37 with a typical font, which gives a maximum of 4 panes. Set HOLLYWOOD_RANDOM_PANES=0 to always use
the maximum.
The CPU limit counts the CPUs that the container can see, not the CPUs of your computer. On Linux the two numbers are the same. On a Mac, Docker runs in a virtual machine, so the container sees only the CPUs that the virtual machine has.
Each pane keeps its widget for 30 to 45 seconds, then swaps in another unused widget. Every pane picks its own time, so the panes change at different moments. Every 5 minutes the window is rebuilt: one pane stays, the others are replaced, a new number of panes is picked, and the panes are laid out again at random.
When the pane count is even, all the panes get the same size, give or take one cell for the borders. even-layout.sh
arranges them in a grid. It picks the grid whose panes are closest to 2.5 times wider than tall, which looks about
square in a terminal. Four panes make a 2 by 2 grid, six make 3 columns by 2 rows, and eight make 4 columns by 2 rows.
The grid is rebuilt every time the launcher rebuilds the window. An odd pane count keeps the random layout, so the
panes have different sizes.
Some widgets stop working in a small pane. The image runs every widget through a guard script (widget-guard.sh).
The guard checks the pane size when the widget starts and again after every resize. If the pane is too small, the
guard stops the widget and starts a different one that fits.
| Widget | Minimum columns x rows |
|---|---|
atop | 60 x 24 |
bmon | 48 x 26, or 141 x 18 (it asks you to enlarge the window below this) |
btop | 60 x 8 (all four boxes need 80 x 24) |
figlet | 57 x 7 |
sshart | 20 x 12 |
All other widgets run in any pane size. To change a minimum or add a widget, edit the MIN_ tables and the
min_rows function at the top of widget-guard.sh.
On a 161x37 terminal with 4 or more panes, no pane is 24 rows tall, so atop cannot run. A layout with 2 or 3 panes
has room for it.
No two panes run the same widget. Each running widget holds a claim in /tmp/hollywood-claims, and a pane that
starts or switches picks a widget that nobody else holds. If no unused widget fits in a new pane, the pane closes
instead of repeating a widget. This only happens with many small panes, for example 16 panes on a 320x90 terminal.
When a pane is ready to swap and no other widget is free, it keeps its current widget.
Hollywood has no btop widget, so the image adds one (btop-widget.sh). btop shows four boxes: the CPU, the
memory, the network and the processes. All four need a pane of at least 80 columns by 24 lines. A smaller pane gets
only the CPU box, which fits down to 60 columns by 8 lines. In a 4-pane layout at 161 x 37 the panes are about
80 x 17, so they show the CPU box. By default btop updates every 2000 ms. The widget sets 100 ms, the fastest that
btop allows, so the graphs move smoothly.
The widget picks the boxes from the pane size when it starts. If you resize the pane across the 80 x 24 edge, it
starts btop again with the boxes that fit. When the widget guard stops it, the widget puts your terminal back the
way it was, because btop does not do that itself.
To run just this widget:
docker run -it --rm --entrypoint /opt/hollywood/lib/hollywood/btop mapitman/hollywood-directors-cut
Press q to leave btop. The widget then starts it again, so press ctrl-c to stop the widget.
The image replaces Hollywood's mplayer widget with two small files, mplayer-widget.sh and
soundwave-render.py.
The video is a pre-rendered animation of an audio waveform, and it has no sound track. The widget asks mplayer to
crop the video to the rows where the waveform is, scale it to your pane, and send the raw frames to the renderer. The
renderer draws each terminal cell as a half block, so every cell shows two pixels in true color. When the pane
changes size, the widget starts again at the new size. A pane with an odd width leaves its last column empty.
To run just this widget:
docker run -it --rm --entrypoint /opt/hollywood/lib/hollywood/mplayer mapitman/hollywood-directors-cut
Press ctrl-c to stop it. Run reset afterward if your cursor stays hidden.
The jp2a widget shows every JPEG it finds under /usr, one after another, except the map picture, which the map
widget shows. The image adds the 171 wallpaper photos from Debian's plasma-workspace-wallpapers package (the KDE
Plasma wallpapers) in /usr/share/wallpapers. The package's copyright file is in
/usr/share/doc/plasma-workspace-wallpapers/copyright, and Debian lists the wallpapers as GPL-2+.
The image replaces Hollywood's jp2a and map widgets. image-widget.sh is the jp2a widget, map-widget.sh is
the map widget, and both draw with image-render.py. Each picture is scaled to your pane and drawn with half
blocks in the 256-color palette, so every terminal cell shows two pixels. The picture keeps its shape and sits in
the middle of the pane, with black bars where the shapes differ. The jp2a widget keeps each picture for 3 seconds.
The map widget draws the map once. A pane of 120 x 36 cells has only 120 x 72 pixels, so the pictures are blocky.
When the pane changes size, the widgets draw the picture again.
The widget never needs more than a few hundred columns of pixels, so the build shrinks the big photos with
shrink-jpeg.sh: photos 3000 pixels wide or more to a quarter of their size, and photos 1500 pixels wide or more to
half. That cuts the wallpapers from about 95 MB to 23 MB. The build fails if fewer than 150 wallpapers are
installed.
To run just one of these widgets, use jp2a or map as the last part of the path:
docker run -it --rm --entrypoint /opt/hollywood/lib/hollywood/jp2a mapitman/hollywood-directors-cut
docker run -it --rm --entrypoint /opt/hollywood/lib/hollywood/map mapitman/hollywood-directors-cut
The Docker build applies one patch, and the patch must match Hollywood's code exactly. If a new Hollywood changes the code around the patch, the build fails, so a broken launcher can never end up in the image.
launcher.patch makes three changes to the Hollywood launcher:
even-layout.sh, which gives an even number of panes the same
size.pane-count.sh for a new pane count.The patch also adds a notice to the launcher that says it was modified, as the Apache License asks.
Byobu asks which mode ctrl-a should use the first time you press it. The image answers that question when it is built. Ctrl-a is the GNU Screen prefix (option 1), so you never see the question.
just build
just run
just build tags the image with both of its names, mapitman/hollywood-directors-cut and mapitman/hollywood.
just run names the container hollywood, so you can stop it with docker stop hollywood.
Why I cut each scene the way I did.
debian:trixie-slim is a named release, so the base does not change between builds except
for security fixes. It has every tool the widgets need, including mplayer.1.25 (4bfa297), so the
Hollywood scripts do not change between builds. This version has all 21 widgets. Its launcher passes the values of
-s and -d to its own tmux session, which the entrypoint needs. Its sshart widget works with current OpenSSH.bmon graph covers 60 seconds of history, so a
pane that lasts 10 seconds shows only the first sixth of it. A pane that lasts 30 to 45 seconds shows at least
half. The code widget shows each file for 2 seconds and the bat widget for 3, so 10 seconds is only a few
files.atop asks for 60 x 24, and bmon asks you to enlarge the window. With 4 panes at 161x37 each pane is
at most 18 rows tall. A pane also shrinks while the launcher splits later panes, so the guard checks again on every
resize.jp2a widget. The image had one JPEG of its own, so the widget showed
the same picture over and over. Debian has no wallpaper package with many JPEGs except the KDE Plasma one, which
has 171. Hollywood's jp2a widget also draws each picture as letters in the eight basic terminal colors and
changes pictures twice a second, which is too fast to see them. The new viewer draws each picture in 256 colors
with half blocks, the same way as the new mplayer widget, and keeps it for 3 seconds. The map widget printed
its picture again every second, so its pane scrolled all the time. It now draws the map once with the same viewer.btop widget. Hollywood has no widget for btop, a monitor that looks more modern than htop and atop.
btop needs 80 x 24 for its four boxes, and the panes of a 4-pane layout on a 1080p screen are about 80 x 17, so
a plain btop would almost never fit. With only the CPU box it fits in 60 x 8, so the widget shows that box in
small panes and all four boxes in big ones. It also updates twenty times as fast as btop does by default: every
100 ms, the fastest that btop allows, instead of every 2000 ms. Counting tmux, which draws the faster updates,
that costs about 3% of one core in a normal pane and 11% in a very large one, and 6 MB of memory.mplayer widget. Hollywood plays the sound-wave video at 100 times normal speed. In a 100 x 18 pane
that redraws the terminal about 950 times a second, which flickers. It also draws the video with libcaca, which
puts a random-looking letter on every cell, and the letters change on every frame. libcaca has no setting for
that. The waveform covers only a thin band across the middle of the video, so the top and bottom of the pane stay
black, and in quiet passages only the center line shows. The new widget crops the video to the waveform, scales it
to the pane, and draws it in true color with half blocks. The picture has no letters and no screen wipe. In
testing, it used about 20% of one core in a 161 x 37 pane and about 36% of one core in a 237 x 61 pane.cmatrix and mplayer hide the cursor, switch to the alternate screen and turn on
mouse reporting. They cannot undo this when the container stops, so the terminal had no cursor afterward.man and code widgets need them.mapitman/hollywood-directors-cut. Docker Hub has no alias feature, so the same image is also published as
mapitman/hollywood, and commands that use the old name keep working.Written by Dustin Kirkland. Re-edited by Mark Pitman. Wallpapers from the KDE Plasma set, by way of Debian. No terminals were harmed in the making of this image. 🎬
The files in this repository are licensed under the MIT license (see LICENSE). Hollywood is licensed under the
Apache License 2.0 (Copyright 2014 Dustin Kirkland), and the wallpapers are GPL-2+. THIRD-PARTY.md lists each part
that comes from another project, its license, and what this project changed. The image carries the same files in
/usr/share/doc/hollywood.
Content type
Image
Digest
sha256:5591fb9a4…
Size
295.3 MB
Last updated
8 days ago
docker pull mapitman/hollywood-directors-cut