Save and Restore an ncurses Screen with scr_dump
scr_dump freezes an ncurses application's virtual screen into a file you can reload later, handy for a test fixture or a captured error state. Allow about 20 minutes if you already have a C compiler and an ncurses development package. The dump is application data, not a terminal recording or a portable screenshot.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Check the local ncurses installation
This guide follows the installed ncurses 6.4 documentation. scr_dump is a function in the curses library, so there is no ordinary scr_dump command to run from a shell. You need the runtime library to use an existing program, and the development headers and linker files to compile the examples below.
$ dpkg-query -W -f='\${Package} \${Version}\n' ncurses-bin
ncurses-bin 6.4+20240113-1ubuntu2.2
$ man 5 scr_dump
Your package revision may differ. The version boundary that matters is ncurses 6: its dump format is textual and starts with a magic header. The local manual describes the format as ncurses 6.4, so do not generalise these details to another curses implementation without checking.
2. Write a small dumper
Call scr_dump after drawing and refreshing the screen. It writes the virtual screen, represented by curscr, to the filename you provide. This example writes a new file in the current directory and reports a failure through the function's ERR return value.
#include <curses.h>
int main(void)
{
initscr();
addstr("Screen saved by ncurses\n");
refresh();
int result = scr_dump("screen.dump");
endwin();
return result == OK ? 0 : 1;
}
Compile it with the wide-character ncurses library if that is the development setup on your machine:
$ cc -Wall -Wextra -o save-screen save-screen.c -lncursesw
Run it from a real terminal, not from a pipeline that has no terminal attached:
$ ./save-screen
Screen saved by ncurses
$ printf 'exit status: %s\n' "$?"
exit status: 0
There is no elevated-privilege step. Choose a directory where your user can write, and do not point the filename at a system file or a shared location unless you have checked its permissions.
Checkpoint: confirm the dump
Inspect the file without editing it. The ncurses 6 format begins with four octal byte escapes followed by the text ncurses, and file may recognise it as an ncurses screen image:
$ file screen.dump
screen.dump: ncurses screen image
$ sed -n '1,8p' screen.dump
\210\210\210\210ncurses 6.4...
_cury=...
...
The exact header version, cursor values and rows depend on the library and the screen contents. Do not treat the dump as a stable text interchange format just because most of it is readable: it contains escaped attributes, dimensions and internal state that should be read by ncurses itself.
3. Restore the screen in a curses program
scr_restore loads a dump into the virtual screen. It does not refresh the terminal, so call refresh or doupdate afterwards. A minimal restore program:
#include <curses.h>
int main(void)
{
initscr();
int result = scr_restore("screen.dump");
if (result == OK) {
refresh();
getch();
}
endwin();
return result == OK ? 0 : 1;
}
Compile and run it in the directory containing the dump:
$ cc -Wall -Wextra -o restore-screen restore-screen.c -lncursesw
$ ./restore-screen
$ printf 'exit status: %s\n' "$?"
exit status: 0
Press a key when the restored screen is visible. If the file cannot be opened or is invalid, the function returns ERR, and the example leaves curses mode and returns a non-zero status.
4. Understand size and compatibility limits
- A different screen size still loads. ncurses truncates or fills as necessary, so a successful restore does not prove every row and column survived. Check the restored layout in the target terminal before using the result operationally.
- There is no standard screen-dump format. ncurses 6 can read legacy ncurses 5 dumps, but dumps from System V curses, PDCurses or another implementation are not automatically interchangeable. Keep the producer and consumer within the compatibility range you have actually tested.
- A dump is not a portable screenshot. The file does not preserve terminal colour-pair definitions as a self-contained image, and the terminal emulator, terminfo entry and receiving application still affect what you see.
5. Handle failure without destroying the original
Writing to an existing filename replaces its contents. If the current dump matters, save a copy before rerunning a program that writes that path:
$ cp --preserve=all screen.dump screen.dump.backup
$ ./save-screen
$ ./restore-screen
Warning
Keep the backup until the new dump has been restored and checked. Removing it with rm is irreversible, so do that only after verification. For an ERR result, first check the path and permissions, then check that the consumer is using curses and that the file was produced by a compatible scr_dump call. Re-running as root will not repair a malformed dump.
Done means
- The application calls scr_dump after drawing and checks for
OK. - The dump is kept as application data, with its producer and ncurses version recorded.
- The restore path checks scr_restore, then calls
refreshbefore displaying the result. - A changed terminal size is tested rather than assumed to preserve every cell.
- Important dumps have a verified backup before replacement.