Escape and Unescape Text with debconf-escape
Debconf's escape capability wants backslashes and newlines written as two-character sequences, and debconf-escape converts between them. The local command is from debconf package version 1.5.86ubuntu1. The examples use a POSIX-style shell and only write to standard output.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need: the
debconfpackage and a shell. No root access. - What it will not do: the command does not enable the capability, change a debconf question, or send a protocol request on its own. It only converts text that some other debconf client or program is about to send or has just received.
1. Check the installed command
Ordinary, read-only checks, worth doing before you build anything on top:
$ command -v debconf-escape
/usr/bin/debconf-escape
$ dpkg-query -W -f='${Package} ${Version}\n' debconf
debconf 1.5.86ubuntu1
The manual gives two forms. debconf-escape -e reads unescaped text and escapes it; debconf-escape -u reads escaped text and unescapes it. Both read standard input and write to standard output. There is no filename argument in the documented interface.
Checkpoint
If command -v finds nothing, install or repair the package through your normal process. Do not work around a missing command by copying a binary in from another host.
2. Escape text before an escape-capable debconf request
Use -e when the text you are holding has real newline characters and real backslashes. This example has one backslash in the first line and two newline characters overall:
$ printf 'path\\name\nnext line\n' | debconf-escape -e
path\\name\nnext line\n
- Backslashes double. One in, two out.
- Newlines become the two characters
\n. Even the final newline from the input gets escaped. - It only looks like one line. On screen it reads as a single line, but it carries the full escaped protocol representation.
This matters when you are building a command for a debconf client with the escape capability set: in that mode debconf expects backslashes and newlines written as \\ and \n. The filter prepares the value; it does not negotiate the capability or send anything.
For a file, redirect standard input rather than inventing a filename option:
$ debconf-escape -e < message.txt > message.escaped
Warning
Redirection can silently overwrite an existing destination. If that file matters, write to a new name such as message.escaped.new, inspect it, then replace the old file on purpose. The command itself changes nothing persistent unless your shell redirects its output into a file.
3. Unescape a debconf reply
Use -u for text coming back from an escape-capable exchange. Here the single-quoted shell argument holds two literal backslashes and the two-character sequence \n, and printf %s passes it through unchanged:
$ printf '%s' 'path\\name\nnext line\n' | debconf-escape -u
path\name
next line
The output now has one backslash on the first line and a real line break before next line; the trailing escaped newline becomes the final line break you see after the second line. The single quotes are doing real work here: they stop the shell interpreting the backslashes before debconf-escape ever sees them.
Common trap: do not use echo to build test data. Its handling of backslashes and options differs between shells. Use printf, and be deliberate about whether you are supplying literal characters or shell escape sequences.
4. Prove that both directions round-trip
The fastest safe check for a script that will handle multi-line values: run both directions and confirm you get the original byte stream back.
$ printf 'path\\name\nnext line\n' | debconf-escape -e | debconf-escape -u
path\name
next line
$ printf 'path\\name\nnext line\n' | debconf-escape -e | debconf-escape -u | od -An -tc
p a t h \ n a m e \n n e x t l i n e \n
od is deliberately less pretty than a terminal display: it shows the backslash as a character and \n as an actual newline marker. If your real input has tabs, carriage returns, or non-ASCII text, add those to the test and compare with a byte-level tool. The manpage documents escaping for backslashes and newlines only; do not assume any other control character gets special treatment.
Checkpoint
In a script, check the exit status alongside the visible output:
$ set -o pipefail
$ printf 'path\\name\nnext line\n' | debconf-escape -e | debconf-escape -u > roundtrip.txt
$ printf 'pipeline status: %s\n' "$?"
pipeline status: 0
pipefail is a Bash feature, among others, and debconf-escape does not require it. Without it, check each stage of the pipeline separately if a failed filter has to stop the script.
5. Keep the protocol boundary explicit
Only apply -e when the receiving debconf conversation actually has the escape capability enabled. Apply it to an ordinary, unescaped conversation and you corrupt the data: a literal backslash or newline can arrive wrong. The same goes in reverse: run -u over ordinary prose and a literal \n can turn into an unwanted line break.
For a real integration, keep the conversion tight against the protocol boundary: escape a value right before you write the command, unescape a reply right after you read it, and hold on to the original value in your program for as long as you can. That makes logging, testing, and error recovery far easier than passing already-escaped strings through several unrelated functions.
The command validates nothing about a complete debconf command. It will not add a command name, quote a question name, check a response code, or make a client safe against untrusted input. Keep following the debconf protocol rules for those parts, and treat values from users or external files as data, never as shell syntax.
6. Recover from a bad conversion
If a generated file looks wrong, stop before it reaches a debconf client. Re-run the conversion to a separate temporary name, inspect it, and keep the original until the replacement passes a round-trip test:
$ debconf-escape -e < message.txt > message.escaped.new
$ debconf-escape -u < message.escaped.new > message.restored.new
$ cmp -- message.txt message.restored.new
$ printf 'round trip: %s\n' "$?"
round trip: 0
cmp returning zero means the restored file matches the original byte for byte. Non-zero means preserve both files and inspect the first difference; do not overwrite the source just to make the check pass. Once the new file is confirmed, use your normal reviewed file-replacement process. No elevated privilege is needed unless the files sit in a protected directory.
Done means
- Identified the installed package and executable as debconf 1.5.86ubuntu1.
- Used
-eonly for real backslashes and newlines going into an escape-capable conversation. - Used
-uonly for escaped text coming back from that conversation. - Round-tripped the text and got the original back, backslashes and newlines included.
- Wrote file output to a new name until
cmpconfirmed it. - Changed no debconf configuration, service, question, credential, or system file.