Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Post History

66%
+2 −0
Q&A Safe handling and display of untrusted data in the terminal

How about BSD vis? It's basically perfect for this. It translates all unprintable characters into escape sequences like \^C or (for characters above 128) \M-A. A corresponding unvis program can tr...

posted 3mo ago by forestbeasts‭  ·  edited 3mo ago by forestbeasts‭

Answer
#2: Post edited by user avatar forestbeasts‭ · 2026-06-09T11:19:52Z (3 months ago)
Mention unvis
  • How about BSD `vis`? It's basically perfect for this.
  • It translates all unprintable characters into escape sequences like `\^C` or (for characters above 128) `\M-A`.
  • Unfortunately we don't know of any good way to install it on our Debian box, there doesn't seem to be a package for it. So we wrote our own at some point. It's pretty simple.
  • ```
  • // vis.c
  • // written by Topaz <[email protected]>
  • #include <stdio.h>
  • int main (int argc, char **argv) {
  • int c;
  • while ((c = getchar()) != EOF) {
  • int printable = 0;
  • if (c >= 32 && c < 127) {
  • printable = 1;
  • }
  • if (c == ' ' || c == '\t' || c == '\n') {
  • printable = 1;
  • }
  • if (c == '\\') {
  • printf("\\\\");
  • } else if (printable) {
  • putchar(c);
  • } else {
  • if (c & 0b10000000) {
  • // high bit set, M-x
  • c -= 128;
  • if (c < 32 || c == 127) {
  • printf("\\M^%c", (c + 64) % 128);
  • } else {
  • printf("\\M-%c", c);
  • }
  • } else {
  • // 0x7F should be \^?,
  • // a control character but +64 would be >128;
  • // so wrap it around
  • printf("\\^%c", (c + 64) % 128);
  • }
  • }
  • }
  • }
  • ```
  • How about BSD `vis`? It's basically perfect for this.
  • It translates all unprintable characters into escape sequences like `\^C` or (for characters above 128) `\M-A`. A corresponding `unvis` program can translate it back (it's unambiguous because `vis` also doubles backslashes in the input).
  • Unfortunately we don't know of any good way to install it on our Debian box, there doesn't seem to be a package for it. So we wrote our own at some point. It's pretty simple.
  • ```
  • // vis.c
  • // written by Topaz <[email protected]>
  • #include <stdio.h>
  • int main (int argc, char **argv) {
  • int c;
  • while ((c = getchar()) != EOF) {
  • int printable = 0;
  • if (c >= 32 && c < 127) {
  • printable = 1;
  • }
  • if (c == ' ' || c == '\t' || c == '\n') {
  • printable = 1;
  • }
  • if (c == '\\') {
  • printf("\\\\");
  • } else if (printable) {
  • putchar(c);
  • } else {
  • if (c & 0b10000000) {
  • // high bit set, M-x
  • c -= 128;
  • if (c < 32 || c == 127) {
  • printf("\\M^%c", (c + 64) % 128);
  • } else {
  • printf("\\M-%c", c);
  • }
  • } else {
  • // 0x7F should be \^?,
  • // a control character but +64 would be >128;
  • // so wrap it around
  • printf("\\^%c", (c + 64) % 128);
  • }
  • }
  • }
  • }
  • ```
#1: Initial revision by user avatar forestbeasts‭ · 2026-06-09T11:18:27Z (3 months ago)
How about BSD `vis`? It's basically perfect for this.

It translates all unprintable characters into escape sequences like `\^C` or (for characters above 128) `\M-A`.

Unfortunately we don't know of any good way to install it on our Debian box, there doesn't seem to be a package for it. So we wrote our own at some point. It's pretty simple.

```
// vis.c
// written by Topaz <[email protected]>

#include <stdio.h>

int main (int argc, char **argv) {
	int c;
	while ((c = getchar()) != EOF) {
		int printable = 0;
		if (c >= 32 && c < 127) {
			printable = 1;
		}
		if (c == ' ' || c == '\t' || c == '\n') {
			printable = 1;
		}
		if (c == '\\') {
			printf("\\\\");
		} else if (printable) {
			putchar(c);
		} else {
			if (c & 0b10000000) {
				// high bit set, M-x
				c -= 128;
				if (c < 32 || c == 127) {
					printf("\\M^%c", (c + 64) % 128);
				} else {
					printf("\\M-%c", c);
				}
			} else {
				// 0x7F should be \^?,
				// a control character but +64 would be >128;
				// so wrap it around
				printf("\\^%c", (c + 64) % 128);
			}
		}
	}
}
```