return to table of content

Serving my blog posts as Linux manual pages

godelski
33 replies
22h43m

I'm pretty sure the OP is intentionally not doing this because piping commands/things-from-the-internet into "bash" (or anything else) is generally considered bad practice.

For me, I'm all for this. Anyone that is aware of the security implications is extremely likely aware of how to make the conversion like you've provided. In that case, no reason to tell people, because they already know. But it's not a great thing to tell noobies to do because they will get burned. So don't tell them. As they advance they'll naturally learn about this feature. And hopefully they have learned the implications by the time they learn how to do this.

(not me): https://www.seancassidy.me/dont-pipe-to-your-shell.html

_joel
9 replies
22h4m

There's not much difference doing a pipe or using and intermediary file and "excecuting" that straight away. There's no manual step in the documentation there to read the output before it's run.

godelski
5 replies
20h47m

This is not accurate. If the download gets interrupted bash will execute the partial line. That means `rm -r /tmp/foo.ext` or `rm -r ${HOME}/.tmp_config` can execute as `rm -r /`.

This can be mitigated by wrapping the script, but clearly no one is looking at the code so this isn't really verified anyways. And it's not like we see that all the time.

Edit:

But my main point is about habits. There's the concern mananaysiempre brings up[0], but either way, it is best to be in good habits.

[0] https://news.ycombinator.com/item?id=39554895

fragmede
2 replies
14h16m

thankfully rm -r / doesn't work on modern systems, though that doesn't invalidate your point.

godelski
1 replies
11h46m

On what system are you talking about? I mean it won't kill everything because sudo but everything you have permissions to are still in danger

prmoustache
0 replies
8h20m

Which usually include your most valuable data.

Nobody cares about losing a system. This is the data it is hosting that is valuable and takes the most time to recover from a backup.

_joel
1 replies
19h4m

From the post

curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > post.page && man ./post.page

If curl's process is interupted, it'll generate a non-0 exit code and the man command won't be exectued. That's how double ampersands work in shell.

godelski
0 replies
16h10m

I think you've missed the context of my comment. We're talking about `curl | man` not `curl && man`. You're right, `&&` doesn't have that risk. But `|` sure does.

jmb99
2 replies
20h31m

There definitely is a difference. See [1] (or [2] since the original site has misconfigured TLS). Long story short, using some fairly trivial heuristics, a malicious server could change its response when it detects its output being piped to a shell rather than saved to a file. Thus, a security-minded person downloading the file (who could inspect it) would be given a clean copy, but someone less security-minded piping it straight to bash would be given the malicious copy. The security-minded person wouldn't be able to warn people not to pipe the script to a shell, since it appears safe.

[1] https://www.idontplaydarts.com/2016/04/detecting-curl-pipe-b...

[2] https://web.archive.org/web/20240228190305/https://www.idont...

rezonant
0 replies
18h46m

This is extremely specifically is about detecting that Bash is pulling on the stream, by using it's line by line interpretation to do a timing attack. It's not clear there's a timing difference between pushing the stream to disk versus pushing the stream to man, since it seems fairly likely that man would read the entire file into memory before operating on it (at least modern man)

_joel
0 replies
18h56m

This is piping to man, not bash.

Interesting vector if you're worried about people piping into man from curl, but there you go.

globular-toast
6 replies
22h31m

Piping to your shell and piping to `man` are not the same thing.

The really dangerous thing is copy/pasting from a browser to your terminal. Always do Ctrl-X Ctrl-E to open an editor, paste it in there, then inspect it before saving/closing the editor to run the command.

vladxyz
3 replies
21h41m

Aren't they? Are you sure piping to 'man' can't result in arbitrary code execution?

The two things you need to be able to say you trust are your CA store, and the source of your curl -> shell.

globular-toast
1 replies
21h24m

No, they're not the same thing! It's not piping to your shell! The shell's single purpose is to execute code. Man is not supposed to do that and it would be considered a huge security issue if it could. In any case, how would you check the downloaded file? With a text editor? Are you sure that can't result in arbitrary code execution?

AlecSchueler
0 replies
20h35m

Man can run groff which can in turn run arbitrary subprocesses.

johannes1234321
0 replies
19h37m

Even if it were:

There is no practical difference. "Nobody" will inspect the man page using a different viewer first. So if I download to disk and then view via man or directly via man is no difference.

A shell script one might inspect first using some viewer. While only few probably do.

crtasm
1 replies
22h9m

Never knew that shortcut, useful!

godelski
0 replies
20h42m

I only recently learned of it myself despite being on nix for over a decade and reading many advanced bash shortcut blogs. IDK why it isn't well known.

For zsh users see here: https://nuclearsquid.com/writings/edit-long-commands/

Note: this can be tricky depending on where it goes in your zshrc. If you use a plugin manager (like Sheldon) then this should be above that. I ended up with this and it works well on OSX and linux

  autoload -U edit-command-line
  # Emacs style (<C-x><C-e>)
  zle -N edit-command-line
  # make sure `set -o vi` is above this line
  bindkey '^xe' edit-command-line
  bindkey '^x^e' edit-command-line
  # (VIM) Use visual mode
  bindkey -M vicmd v edit-command-line

jimmaswell
5 replies
21h39m

Has there been a single recorded case of malware getting around this way?

godelski
4 replies
20h5m

I'm sorry, your argument is... what exactly? That we shouldn't take simple or even trivial preventative measures that also reduce other potential problems because we... haven't seen anybody abuse such a thing before? Really?

What a terrible argument. Not it's trivial to resolve. Why not just fix things that we know are problems or can lead to serious problems instead of waiting for it to become a problem where it'll then be FAR more work to clean it up?

Seriously, you're a human, not a bug. You have the ability to solve things before they become problems. Use it.

While I'm not sure of a specific example, I feel quite confident in saying that this has been done before.

rezonant
1 replies
18h41m

There was no argument here, only a question. And it's a fair question to ask for the purposes of discussion.

You're right, piping to sh is definitely a risk, and we should do better as a community, and not make users normalized to piping to sh.

godelski
0 replies
15h59m

It appeared as a rhetorical question used to rebut the claim. Maybe I misinterpreted it. Fair. But that is a possible interpretation.

But as you can see elsewhere, we shouldn't pipe streams into anything. It's just not hard to avoid this. A few extra characters and you're good to go. Let's take rust for example. Users are copy pasting anyways

They give

  curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
But why not

  curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /tmp/rust_install.sh && sh /tmp/rust_install.sh
For user experience, it is till a one liner, but it is infinitely better. Still has some risks, but a lot less. (at least rust does wrap the install so you don't run the risk of partial line execution) And it gives the user a way to verify that the file was correct if they provide a checksum.

There's just no good reason to not do this. We especially shouldn't be teaching noobies to pipe streams into any command. Let's be real, most people don't know linux well, even if they use linux.

jimmaswell
1 replies
13h15m

If you're willing to run an executable installer from a website then piping into sh is no better.

godelski
0 replies
51m

Read elsewhere. Piping can be dangerous if there's a disconnect. You can also detect piping server side. Piping is strictly worse. Convenient, yes, but 99% of the commands can non-streams and no difference for the end user who is copy pasting it.

hk__2
4 replies
21h49m

I'm pretty sure the OP is intentionally not doing this because piping commands/things-from-the-internet into "bash" (or anything else) is generally considered bad practice.

It’s generally considered bad practice only for bash and similar commands that execute their input. It’s not a bad practice at all for commands that just display or transform their input, like `man`, `less`, `ffmpeg`, etc.

codelobe
2 replies
20h7m

[insert confused trollface]

ffmpeg There is certainly a few hundered exploitable vectors in that program alone... to say nothing of the rest.

When in doubt, spin up a VM to run the random untrusted thing -- And then go read its mailing list/issue tracker for known VM escaping exploits. I have a machine setup to test malware, so I just hit my "airgap" switch to isolate the system from my network once the questionable code is in place and ready to run (potentially amok). Study-up about ARP-poison attacks, and remember ARP does not transit to upstream routers/switches (Y "combinate" your network for fun and profit).

Before you assume non malicious simple text output, consider "ANSI" escape code complexity as an intrusion vector for whatever terminal you run. I've got "0-days" for this going back to MSDOS: ANSI Bomb => arbitrary CMD entry. You don't have to take my word for it, your terminal of choice is most certainly vulnerable to some ANSI/escape code related exploit, look it up.

rezonant
0 replies
18h51m

This is why I spin up a VM whenever I want to look at an image. The risk is too great. Even text files, after all we never know if there's a zero day in the UTF-8 decoder. Better safe than sorry.

Wait a minute I just realized there could be a zero day in the VM hypervisor too. I guess I'll just have to buy a fresh Raspberry Pi for each file I want to open.

/s

hk__2
0 replies
8h27m

Fine but we’re not talking about piping random stuff from the Internet here; we’re just using curl as a convenience not to use an intermediary file.

mananaysiempre
0 replies
21h34m

Man on Linux runs groff, which (like the original nroff/troff) is a fully general macro processor in addition to being a typesetting system. I wouldn’t bet on it not being able to launch subprocesses, or especially on it having no overflows and such on untrusted input. I’m not even sure about OpenBSD’s much more limited mandoc.

(Also, I don’t know about ffmpeg as it is somewhat more rare to have it be public-facing, but there have definitely been exploits against ImageMagick, usually targeted at websites using it to process user input.)

godelski
4 replies
20h36m

Can't edit my comment so I'll write as a reply

  This is to all the people saying no difference between downloading and running right away
If the download gets interrupted bash will execute the partial line. That means `rm -r /tmp/foo.ext` or `rm -r ${HOME}/.tmp_config` can execute as `rm -r /`. This can be mitigated by wrapping the script. Best way to do this is wrap the whole script into a function and then execute at the last line[0]. Oh, and you can detect `curl|bash` server side[1]

[0] https://archive.is/20160603044800/https://sandstorm.io/news/...

[1] https://archive.is/20230325190353/https://www.idontplaydarts...

Edit: as an example, rust does the warpping. But they still place this stupid shit on in their install instructions. Bad Rust! Bad!

https://www.rust-lang.org/tools/install

Arnavion
1 replies
15h18m

Best way to do this is wrap the whole script into a function and then execute at the last line[0].

It's not the best way. If your function is named `lsp_init` and your last line is `lsp_init`, a partial line can result in the execution of `ls`.

AFAIK the best way is to just wrap your script in `()`.

godelski
0 replies
15h13m

You're right! That's a good thing to point out. Elsewhere I suggested Rust change their install to this though. Solves pretty much all the probems

  curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /tmp/rust_install.sh && sh /tmp/rust_install.sh
(obviously doesn't solve the problem of inspection, but I think we all know that's not going to happen anyways)

rezonant
0 replies
18h43m

I agree that it's a risk to pipe to sh but that's not what we're doing here, and I'd hope that most of the people aren't saying there's no difference between piping to man and piping to sh.

cyberpunk
0 replies
4h44m

How will it execute the partial line? Interrupted downloads don't just randomly insert <CR>s into the line?

zerojames
10 replies
23h55m

Unfortunately, that command doesn't work on macOS (`/usr/bin/man: illegal option -- l`). I tried to get a one-liner with piping working on my Mac but I always ran into errors. The -l flag doesn't exist in the macOS man implementation (I consulted the man page; meta!).

divbzero
4 replies
23h16m

This doesn’t work because it’s equivalent to piping stdout from curl into stdin for man.

divbzero
1 replies
22h43m

You’re right, it isn’t quite the same as piping.

man <(curl ...) ends up working on Linux but for whatever reason still yields an error on macOS:

  No manual entry for /dev/fd/11

jasomill
0 replies
18h28m

  curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ | mandoc -a
works on macOS (and should also work on (Free|Net|Open)BSD, which ship similar man toolchains).

globular-toast
0 replies
21h55m

It's actually process substitution: https://www.gnu.org/software/bash/manual/html_node/Process-S...

It's essentially running the process in another shell and sending its output to a tempfile. The name of that file is then substituted in the original command. So, in theory, equivalent to `inner > /tmp/file; outer /tmp/file`. This works with programs that don't read from stdin, or need two or more inputs, for example.

BossingAround
0 replies
23h30m

Nope

jolmg
2 replies
23h46m

The `-l` can be skipped (probably because there are `/`s in man's argument):

  curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ | man /dev/stdin

divbzero
0 replies
23h17m

This still doesn’t work for me on macOS, perhaps a difference in how /dev/stdin is implemented?

Fortunately, macOS has ZSH as the default shell so the following does work:

  man =(curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/)

BossingAround
0 replies
23h30m

(which still doesn't work on mac)

salviati
2 replies
23h2m

You can save a few chars with a process sostitution instead of a pipe if you're using bash:

    man -l <(curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/)

teaearlgraycold
0 replies
22h59m

And the world rejoiced as the bytes were saved.

hk__2
0 replies
21h48m

If you’re into that you can save four more chars by using `-sLH Accept:text/roff`

yegle
29 replies
23h57m

It would be cool to provide a deb repo as a way of subscribing to your blog.

So `apt update` will pull in all blog posts, `man your-blog` will show the latest post with links to the index of all your other posts.

dcminter
14 replies
21h37m

On the one hand this idea is brilliant - on the other hand if it caught on, there are some obvious opportunities for malware intrinsic to the approach :'(

I think I'd be too chicken to subscribe.

codetrotter
8 replies
19h7m

Make the CI pipeline create a Docker image that contains Debian slim and the man pages installed.

rezonant
6 replies
18h56m

On the other hand, it's Docker, so you know every blog will use their own base image.

astrea
5 replies
13h32m

Guys: Serve your blog via Docker itself. Docker image names are _already_ URLs. You could literally just have people do `docker pull myblog.com/recipes:latest` or `myblog.com/recipes:lasagna`.

Edit: and navigate like so: `docker image myblog.com/recipes` to list all recipes. God I love APIs.

tomxor
2 replies
7h26m

I can't tell how much of this is sarcasm. Turning what started out as a problem of "How do you load arbitrary remote TROFF sources into man" into "throw docker at it" because someone suggested an intermediate solution of "apt" which introduces security issues and no one posed that there might be an alternative that obviates any need for containerization. I mean these two things could be further from each other on the scale of incredibly lightweight to massively heavyweight.

Or maybe this is a microcosm of why docker and kuberwhatever happens so much.

codetrotter
0 replies
6h13m

I can confirm that I was jesting when I said to use Docker here :^)

TeMPOraL
0 replies
7h10m

It's the nerd version of that Reddit pattern of organic comment chain, each reply adding e.g. a line of song - only with pushing an absurd idea to the limits.

I'll bite: with GP's take, docker-compose would make for a good webring/blogroll. Or use it as bookmarking system.

  cd blogs/cooking
  docker-compose up
  # 20 different recipe blogs available as man pages

mrmattyboy
1 replies
12h27m

And add search logic to the tag, so you don't need to know the name of the post, just the right word(s) to find it and let the "I'm feeling lucky" algorithm pick the right one :)

TeMPOraL
0 replies
7h14m

And then someone ports that back to regular Docker, and we get a whole new dimension of software supply chain security issues :).

usr1106
0 replies
11h13m

Docker is the example implementation of "containers do not contain". At least I would use podman.

westurner
4 replies
17h51m

How does HTTP(S) Same Origin policy work with local file:/// URLs?

TIL there's no `ls -al /usr/share/man/** | man --html`; though it would be easy to build one with Python's http.server, or bottlepy, or bash,.

Prompt: An http server ( with bash and /dev/tcp/ ) that serves HTML versions of local manpages with linkification of URLs and references to other manpages

awithrow
3 replies
13h57m

How does HTTP(S) Same Origin policy work with local file:/// URLs?

It doesn't since file:/// is just a uri and not part of the http protocol

westurner
1 replies
11h42m

If I open an HTML copy of a manpage that contains JS from a file:/// URL, can it read other local files and send them to another server with img URLs?

If so, Isn't it thus probably better to run an HTTP server over a permissioned socket than to serve static HTML [manpages] from file URLs [in a [DEB] package]?

awithrow
0 replies
4h37m

file:/// is always going to be local to the machine reading the URI. So if you're serving a page that has a file:/// uri in it and someone on another machine clicks on it, they wont be seeing the file (unless they happen to have the same path on their machine). If the goal is get them that file, then yes, it'll need to be served.

zerojames
6 replies
23h56m

_adds to their TODO list :D_

tutfbhuf
5 replies
22h47m

Please also create an AUR package for Arch Linux.

basilgohar
4 replies
22h37m

Release as a Flatpak and make it distro agnostic!

gkbrk
3 replies
22h36m

Make it even better and release an AppImage!

edvinbesic
2 replies
22h31m

Even even better, put it on the web so it’s accessible from anywhere

abulman
1 replies
22h5m

wow, there. Lets not get crazy there. It's plenty enough to support multiple package managers, but what you are considering is just too much!

hk1337
0 replies
19h50m

Okay, just create an iOS application.

dredmorbius
2 replies
15h9m

There's some precedent for this. Debian used to provide access to the now-defunct Linux Gazette, and still offers numerous informational packages (package docs, manpages, info pages, RFCs, Linux HOWTOs, and more), all of which can be served locally through the dww package, "Read all on-line documentation with a WWW browser":

<https://packages.debian.org/bookworm/dwww>

(Joerg Jaspert was the former maintainer of Linux Gazette packages: <https://people.debian.org/~joerg/> (2002).)

This remains to me one of the best examples of integrating information delivery and documentation on an operating system I've ever encountered. Notably, it makes both manual and info documents more useful and usable than their traditional terminal-based interfaces.

There are Debian-associated blogs (Debian Planet), though I don't believe that was ever packaged for Debian itself.

Frankly, RSS is probably a better option for blog subscription.

anthk
1 replies
8h47m

You could read LG without dwww just fine by just pointing the file:/// path.

I remember getting all of those with the Debian Sarge DVD's, good stuff, among the Anarchist Faq, the 'Derivations' math book, and tons offline documentation when I didn't have internet at home.

dredmorbius
0 replies
7h49m

dwww need not be limited to localhost access, meaning that a single Debian system can serve docs to others (LAN, intranet, public Internet, ...).

Of course, all of the documentation that's exposed via dwww is accessible on that host's filesystem. But dwww also provides a few additional affordances: Web-formatted output, a directory of installed documentation (organised by source / type), and (if you have swish++ installed), full-text search.

potta_coffee
1 replies
20h26m

Release your blog as an Electron application please.

usr1106
0 replies
11h7m

How would that fit on a RK07 disk?

zerojames
0 replies
20h57m

This is now in progress.

https://github.com/capjamesg/jamesg.blog.deb has all you need to build a man-page-only deb file using:

git clone https://github.com/capjamesg/jamesg.blog.deb cd jamesg.blog.deb dpkg-deb --build --root-owner-group jamesg.blog sudo dpkg -i jamesg.blog.deb

You should see:

... Processing triggers for man-db (2.9.1-1) ...

Which indicates the man page for `man jamesg.blog` is available. There is just a placeholder in there for now. I will perhaps finish this tomorrow!

NB: This may become a blog post soon :D

out_of_memory
0 replies
22h29m

first thing came to my mind when i read the blog. it would be a very cool thing. i hope this becomes a thing.

godelski
8 replies
20h1m

Please don't... Actually yrro posted something similar 2hrs before you and now we have the whole {curl,wget} pipe into command discussion again...

  Friends don't let friends pipe streams into commands
https://news.ycombinator.com/item?id=39554044

rezonant
7 replies
18h52m

The top reply to that comment rightfully points out that this applies to your shell specifically. This isn't a concern for formats that don't have executable code (and I assume roff doesn't, right?)

You might say, yes, but it's still a good idea to review the file before you open it. OK sure, but that isn't going to work for binary files anyway, so "Friends don't let friends pipe streams into commands" should not be the general rule. "Friends don't let friends pipe streams into shells" is certainly a good enough general rule.

scorpicam
3 replies
17h16m

You execute arbitrary commands with troff. I used this feature a lot for getting output from code samples, but it's definitely a security issue if you don't trust the source. Or, if you think shelling out is too boring, the troff macro language is actually turing complete and is a disturbingly usable for scripting.

cyberpunk
0 replies
4h47m

I'm not convinced there's not some clever way to get roff to make $PAGER run commands; echo <esc>:!cat /etc/passwd etc

rezonant
0 replies
17h13m

Oof, I kind of suspected this might be the case.

godelski
2 replies
16h16m

1. Regardless, it is bad practice. It isn't a good idea to teach people to pipe downloaded content into any command. Regardless of how naive and safe the command seems. You may not know. Especially considering how you aren't guaranteed to run the full contents and may even run partial lines. Just don't get in the habit of streaming anything into a command. Because you'll be more tempted to stream into a different one which might have issues. Running two commands (or &&) just isn't a big deal. Low cost for high reward.

2. The person replying to me mentioned ffmpeg and well... see the reply to them. Parsers may not seem like a big deal, but see this about `cat`[0] or this about `less`[1] (a quick search shows a lot of pipe and pager type of vulnerabilities, including privilege escalation). Programs that look simple and a non-risk are probably actually prime targets for hackers because it can lull someone into a false sense of security.

3. You can detect bash piping server side. There's been a bunch of HN and reddit posts, several have been shared already so I won't repeat.

I'm sticking to:

  Friends don't let friends pipe streams into commands
It's just safer. Risk is pretty low, but does using `&&` or a `;` instead really create a lot more work? How about

  curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > post.page && man ./post.page && rm post.page
This at least guarantees you don't get a truncated execution.You'll delete the file after you close man. This at least guarantees you don't get a truncated execution. Better if we send to /tmp/post.page and not delete, in case something is fuzzy. Both of these also prevent server side detection and possible tomfoolery. /tmp will be cleared on reboot anyways and it's better to have the file in case something DOES happen.

  curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > /tmp/post.page && man /tmp/post.page
[0] https://security.stackexchange.com/questions/56307/can-cat-i...

[1] https://ubuntu.com/security/notices/USN-6664-1

Edit:

groff vulns: https://www.cvedetails.com/vulnerability-list/vendor_id-72/p...

Crestwave
1 replies
9h4m

curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > post.page && man ./post.page && rm post.page

What if I have a post.page in my current directory?

curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > /tmp/post.page && man /tmp/post.page

What if another user runs the command at the same time, then?

Or what if a malicious user creates a 666 mode /tmp/post.page file beforehand, detects when you finish writing to it, then attaches a payload right before `man` reads it?

Unfortunately, there is no perfect solution for this problem; I run arbitrary html, css, and javascript every day by browsing the web. It's debatable whether switching to command chains instead of piping results in overall benefits. Of course, the same goes for vice versa as well.

godelski
0 replies
55m

Sure, but aren't you being pedantic at this point? If you're that concerned, add a small random number. But of course there's no perfect solution. But we still are mitigating the main concerns.

hereonout2
3 replies
22h32m

Should have read the manual.

0xEF
2 replies
21h37m

rtfm.lol I guess

hk1337
0 replies
19h48m

https://rtfm.lol

already taken.

busfahrer
5 replies
23h53m

Speaking of URLs that do fancy stuff on the terminal, I once stumbled upon this one from textfiles.com, it's essentially a short animated movie on the terminal using VT100 terminal codes, all served from a URI. On modern systems you can use rate-limiting to watch it:

curl --limit-rate 1000 http://textfiles.com/sf/STARTREK/trek.vt && reset

(the reset is there because it might mess up your terminal)

Other terminal-powered URIs:

curl cheat.sh/tar (gets examples on how to use the program after the /)

curl wttr.in/berlin (gets weather info with terminal formatting)

ryukoposting
0 replies
14h39m

Wow, this is really cool. It also completely borked my terminal! What fun.

dancek
0 replies
11h29m

Years ago I made an ANSI art viewer with modem speed emulation. It has an outdated mirror of https://16colo.rs/ so most ANSI art that's ever been published is viewable. See e.g.

curl ansi.hrtk.in/ungenannt_1453.ans

anthk
0 replies
21h2m

Use tritty to fake a 1200/9600 BPS baud rate.

masto
4 replies
1d

I don't know why this particular thing set off my pedanticism. Someone is slightly wrong on the Internet! Maybe because it started right off being needlessly Linux-centric. Or that I thought it would be one thing but it turned out to be a brief demo of content negotiation in NGINX.

In any case, a few pointless things that I seem compelled to say:

* It's not returning roff, as such. Those things like `.TH` are not part of roff, they are part of the macro package for writing man pages. * I was disappointed that there was no markdown-to-roff conversion, which seemed like it was going to be the interesting part of this post. At least use one of the existing ones. * On a similar note, this means that the text isn't really formatted correctly. roff is meant for one sentence per line of input, to distinguish between `.` to end a sentence vs. other uses. * Also also wik, this means that any line starting with a `.` will be interpreted as a command, potentially wreaking havoc.

Or maybe I'm just a grumpy old man.

jorams
2 replies
23h52m

* I was disappointed that there was no markdown-to-roff conversion

I found this rather surprising too. Pandoc can trivially convert markdown to man-page roff. Insert that into the given template and it looks like more like an actual man page.

zerojames
1 replies
23h48m

Good suggestion!

Context: All man pages are generated on the fly on GitHub Pages. My site generates ~2500 pages, for which 826 are eligible for a man page. I didn't want to introduce another parser since I just got my site build times down :D

I can counter increased build times with caching, but it gets a bit icky since some blog pages are evergreen (i.e. my blogroll). [insert cache invalidation complaint here] But there's certainly a way!

jorams
0 replies
20h56m

I feel that, build times can be a pain. I'm calling out to pandoc to build a static site and I've had to parallelize it to get build times down, and that's with far fewer pages.

zerojames
0 replies
23h57m

I appreciate you sharing this! I wasn't aware of the exact ontology of how roff vs. man relate, and I went through several iterations of this post trying to get this right. There being other tools -- groff, nroff, etc. -- added to my confusion. A blog post unto itself is "here is what roff/man page/nroff/other variants are, here's how to use them." I would have appreciated a succinct description; I'm sure others would, too.

As for markdown to roff, I thought about it as a v2. As I started to think about implementing a parser, someone shared https://github.com/sunaku/md2man with me, which appears to solve the problem.

I'd need to figure out how to integrate this into my (Python) site that is built on GitHub Pages; a bit of tinkering would be required :D

darkwater
4 replies
20h55m

Maybe I can search the interwebs to answer this question but I prefer to ask the HN crowd. Back in highschool in remember someone (on an HP-UX) showing me that you could jump to any underlined word (referring to a section) by pressing some key combination, but for the life of me I cannot remember which. I already checked man(1) and man(7), and could not find it either. Maybe this is just a fake memory?

epcoa
2 replies
20h41m

I’m not familiar with any custom man viewer functionality but maybe you're thinking of the CDE help viewer, dthelpview which would display man pages.

darkwater
1 replies
20h24m

No, it was in a dumb text terminal. But maybe I just made it up, and I'm confusing it with classic "hjkl" navigation.

enriquto
0 replies
10h54m

you can, from inside vim. You press "K" over a word and it opens the manpage. If you have configured vim as your manpage viewer, you can thus navigate all manpages.

medstrom
3 replies
22h47m

There is an Emacs package that installs Abelson & Sussman's SICP (Structure and Interpretation of Computer Programs) into the Info directory.

Simply type M-x package-install sicp RET

That gave me the idea that one could install a whole bookshelf of blog archives through some modified feed reader. Reading Info in Emacs, you even get bookmarks.

felideon
1 replies
22h40m

FYI, SICP is from Abelson and Sussman.

medstrom
0 replies
22h38m

My bad, thanks.

anthk
0 replies
2h24m

Get chicken-scheme too. Then, as root:

chicken-install srfi-203 chicken-install srtfi216

~/.csirc for sicp:

    (import scheme)
    (import (srfi 203))
    (import (srfi 216))

    (define (inc x) 
      (+ x 1))

    (define (dec x)
       (- x 1))
Then user geiser and geiser for chicken as usual.

ajvpot
0 replies
23h15m

I love pandoc[0] for tasks like this. It supports most markup formats I've needed.

[0]: https://pandoc.org/

worble
1 replies
1d

Cool idea. I'm starting on the timer until we get "serving my blog posts as playable DOOM wads".

vonjuice
0 replies
1d

Add it to the list of the handful of actually cool things that AI could facilitate.

nulbyte
1 replies
1d

I never thought of making a blog post a man page. That's pretty awesome, actually. I'd be interested to see the code for the underlying conversion, but maybe I'll just try my hand at it myself this weekend.

Btw, in Bash, you can use process substitution to avoid littering your folder with files, if you don't want to save them:

$ man <(curl ...)

rahimnathwani
0 replies
23h48m

I'd be interested to see the code for the underlying conversion

The post includes the template he used. You can adapt it to any templating engine or put some placeholders in and use sed or whatever.

adriangrigore
1 replies
22h4m

I prefer my own UNIX web dev solution https://mkws.sh! Man pages ar too much imo.

hk__2
0 replies
21h57m

I prefer my own UNIX web dev solution https://mkws.sh! Man pages ar too much imo.

Those are orthogonal subjects; you could generate your own static page with your generator AND also serve them as manpages. The linked article does not suggest to server manpages to everyone, just to user agents that request them.

Annatar
1 replies
1d1h

One could pipe that output directly to nroff or groff:

  | soelim | tbl | eqn | nroff -man - | $PAGER

  | soelim | tbl | eqn | nroff -man -Tpost - | /usr/lib/postscript/bin/dpost | ps2pdf - > ~/Desktop/blog.PDF

  | soelim | tbl | eqn | groff -Tps -man - | ps2pdf - > ~/Desktop/blog.PDF

anthk
0 replies
21h1m

with groff you don't need soelim | tbl...

just run

       | groff -Tpdf -step -k > ~/Desktop/blog.pdf

urbandw311er
0 replies
19h24m

Little real world application, super fun challenge. This is why I come here.

ubermonkey
0 replies
3h55m

this is gloriously demented.

throwaway81523
0 replies
23h44m

That doesn't look like man pages. Was it supposed to be an example? (EDIT: oh nm, I see, I have to view the image. Nice. But the web view should also look like that.)

I noticed the "written by human, not AI" logo, a little too cute but the sentiment is good. I had been thinking of putting something like "this page created by natural stupidity" in mine.

sureglymop
0 replies
14h3m

I did a somewhat similar thing on my portfolio page. The server recognizes curl and wget and then serves the page as plaintext. If a PDF is requested, it sends my CV. My idea is that if a recruiter overcomes that first hurdle of getting to the CV, then I may as well hear them out.

rahimnathwani
0 replies
23h39m

If you like this you might like mdless, which does exactly what the name suggests.

https://github.com/ttscoff/mdless

pjmlp
0 replies
23h46m

Cool experiment, as means to serve UNIX man pages.

notorandit
0 replies
11h43m

Unix man pages. Man pages were here since long before Linux existed!

jedberg
0 replies
22h55m

Ironically it breaks when you request this page as a man page. :)

heartag
0 replies
1d2h

That's a fun idea, and well executed.

harryvederci
0 replies
21h0m

I feel like this is too accessible.

Anyone doing this but with Vim help files?

gglitch
0 replies
23h47m

Fun project :) Next step: Texinfo, which will output to info, html, and pdf, among others, and which includes links and indexes.

channel_t
0 replies
30m

This is awesome. I would love to see a whole ass social network (or a webring?) that was just a directory of man pages that I could get lost in.

anthk
0 replies
21h5m

WIth mandoc and maybe groff you can typeset pages to man pages, HTML, PS and PDF files.

akritid
0 replies
14h59m

With some plumbing, it should be possible to follow links: match the URL with regex using the terminal and launch the link target in a new window.

_xerces_
0 replies
20h4m

For the lazy or short of time, does with worth with tldr pages :) https://tldr.sh/