Home / Alt manpages / pm-gawk(1)

  • pm-gawk(1)
  • User command
  • linux

Keep gawk State Between Runs with pm-gawk

Ordinary AWK forgets everything the moment it exits, but pm-gawk gives gawk a heap file so variables and functions survive between runs. The examples use GNU Awk 5.2.1 from Ubuntu package gawk version 1:5.2.1-2ubuntu0.1, where persistent memory is provided by pm-gawk. Allow about fifteen minutes, including a small test and a decision about where the heap should live.

This is useful for a long-lived associative array or a shared set of AWK functions. It is not a database, not a backup replacement, and not a way to smuggle arbitrary shell state around. The heap contains program data and code, so pick its location and permissions with the same care you would give a private application data file.

1. Check the installed gawk version

Persistent memory first shipped in gawk 5.2, so check the binary before you build a workflow around it:

$ gawk --version | head -n 1
GNU Awk 5.2.1, API 3.2, PMA Avon 8-g1, (GNU MPFR 4.2.1, GNU MP 6.3.0)
$ command -v gawk
/usr/bin/gawk

Version and feature details can differ on another machine. If the command reports an older gawk, do not assume GAWK_PERSIST_FILE will do anything at all.

2. Create a new zero-filled heap

Choose a directory that is local to the machine and closed off to untrusted users. The backing file has to start empty in the pm-gawk sense: every byte zero. The manual's own example uses a gigabyte; this guide uses a one-megabyte heap for a small demonstration.

$ mkdir -p "$HOME/.local/state/my-gawk"
$ chmod 700 "$HOME/.local/state/my-gawk"
$ truncate -s 1M "$HOME/.local/state/my-gawk/heap.pma"
$ stat -c 'size=%s bytes mode=%a' "$HOME/.local/state/my-gawk/heap.pma"
size=1048576 bytes mode=644

The directory is private, but as the output shows, the file truncate just created may still be readable by other users. Tighten it before anything sensitive goes into the heap:

$ chmod 600 "$HOME/.local/state/my-gawk/heap.pma"
$ stat -c 'size=%s bytes mode=%a' "$HOME/.local/state/my-gawk/heap.pma"
size=1048576 bytes mode=600

Checkpoint

Size should match what you chose, and mode should be private enough for the data going in. Do not point GAWK_PERSIST_FILE at an existing non-zero file, and keep the heap off a GNU/Linux CIFS filesystem: the installed manual warns that CIFS causes problems for the persistent memory allocator.

3. Run gawk with persistence enabled

Set GAWK_PERSIST_FILE for one command at a time while testing. It is an environment setting, not an AWK option:

$ heap="$HOME/.local/state/my-gawk/heap.pma"
$ GAWK_PERSIST_FILE="$heap" gawk 'BEGIN { print ++i }'
1
$ GAWK_PERSIST_FILE="$heap" gawk 'BEGIN { print ++i }'
2

Both commands start a fresh process, but i is script-defined state recovered straight from the heap. Run it once more for a simple sanity check:

$ GAWK_PERSIST_FILE="$heap" gawk 'BEGIN { print ++i }'
3

Setting the variable on every command line makes the boundary visible, and stops an unrelated gawk invocation from accidentally sharing this state.

4. Persist a function as well as a variable

Define a function in one run, then call it from a later run. This is the bit that ordinary file output cannot give you:

$ GAWK_PERSIST_FILE="$heap" gawk 'function bump(x) { return x + 1 } BEGIN { print bump(41) }'
42
$ GAWK_PERSIST_FILE="$heap" gawk 'BEGIN { print bump(41) }'
42

The second command has no function definition anywhere in its AWK program. It succeeding at all shows that bump came straight from the persistent heap. Choose function and variable names deliberately: a later script can pick up old definitions even when its own source looks entirely self-contained.

5. Choose ambient or per-command configuration

For a short session, exporting the environment variable cuts down on repetition:

$ export GAWK_PERSIST_FILE="$HOME/.local/state/my-gawk/heap.pma"
$ gawk 'BEGIN { print ++i }'
4
$ gawk 'BEGIN { print ++i }'
5

Unset it when you need gawk to behave normally again, with no persistence:

$ unset GAWK_PERSIST_FILE
$ gawk 'BEGIN { print ++i }'
1
$ gawk 'BEGIN { print ++i }'
1

Checkpoint

If an ordinary command unexpectedly prints a value left over from an earlier run, check env | grep '^GAWK_PERSIST_FILE='. A shell export follows every child command until you unset it or close the shell entirely.

6. Reset the heap deliberately

Warning

Removing the heap permanently forgets every variable and function in it. This is destructive and cannot be undone unless you kept a copy:

$ cp --preserve=mode "$HOME/.local/state/my-gawk/heap.pma" /path/to/a/backup/heap.pma
$ rm -- "$HOME/.local/state/my-gawk/heap.pma"

Check the path twice before running the removal. For a clean heap afterwards, create a new zero-filled file at the same size and restore its permissions:

$ truncate -s 1M "$HOME/.local/state/my-gawk/heap.pma"
$ chmod 600 "$HOME/.local/state/my-gawk/heap.pma"
$ GAWK_PERSIST_FILE="$HOME/.local/state/my-gawk/heap.pma" gawk 'BEGIN { print ++i }'
1

Do not reach for sudo here unless the chosen directory genuinely needs elevated access. Running the AWK program as root would hand it more access to input files than this feature actually requires.

Done means

  • Confirmed the version. gawk --version reports version 5.2 or later.
  • Created a clean heap. It was zero-filled on a local filesystem, not GNU/Linux CIFS.
  • Verified persistence. Two separate gawk invocations recovered the expected variable value.
  • Confirmed function persistence. A function defined in one invocation was callable in the next.
  • Scoped the environment variable. GAWK_PERSIST_FILE is exported only when persistence is actually intended.
  • Matched permissions to sensitivity. Heap permissions and any reset or backup step match what the heap actually contains.