一个多余的“j”毁了我的夜晚。
A stray "j" ruined my evening

原始链接: https://napkins.mtmn.name/posts/stray-jay.html

作者编写了一个名为“shirts”的简单 Shell 脚本,用于缩短网址并利用 `wl-copy` 自动复制到剪贴板。该脚本运行数月一切正常,直到作者开始使用基于终端的 Signal 客户端 *gurk*。 用户开始反馈通过该应用分享的链接会出现 404 错误。经调查,作者发现 `jq` 在输出结果后添加了一个换行符。在某些终端环境下,这个换行符被解析成了字母“j”,它会自动附加到 URL 末尾并导致链接失效。 问题通过在 `jq` 命令中添加 `--join-output`(或 `-j`)参数得以解决,该参数可以阻止自动添加换行符。作者将此次经历视为一次因终端控制代码和转义序列怪癖而导致的、令人啼笑皆非的教训。

这段 Hacker News 的讨论探讨了数字文本中神秘出现的“j”字符这一困扰用户的常见问题。评论者分析了造成该现象的几种技术原因: * **ASCII 控制码**:换行符(`\n`)表示为 `Ctrl+J`(ASCII 码 10)。当软件错误地处理或渲染这些控制码时,它们可能会显示为字母“j”。 * **字体编码**:有时字符并非表面看起来的那样。一位用户分享了一个趣闻:某封邮件里的“j”实际上是“Wingdings”字体下渲染出的笑脸符号。 * **软件与工具**:讨论指出,许多旧系统、Shell(如 TeX)以及现代的复制粘贴操作可能会损坏换行符,尤其是在终端应用程序或剪贴板管理器之间传递数据时。 * **调试**:对话最后提供了一些实用的技术小知识,例如如何使用 `jq` 等命令行工具去除不需要的换行符。 总之,该讨论帖深入剖析了文本编码和终端遗留行为如何以各种怪异的方式继续困扰着现代软件用户。
相关文章

原文

← back 2026-06-08

Some time ago I decided to wrangle a silly link shortener that I called shirts linkener, shirts for short.

There's nothing special about it in particular, rather it's in my run-once-forget-forever shell script that copies the generated links to a clipboard using wl-clipboard.

#!/bin/sh

shirt=$(curl -s -X POST "$(pass show shirts/url)" \
    -H "Authorization: Bearer $(pass show shirts)" \
    -H "Content-Type: application/json" \
    -d "{\"url\": \"${1?missing url}\"}")

echo "$shirt" | jq
echo "$shirt" | jq -r '.short_url' | wl-copy

Nothing out of the ordinary here. It shortens the link and copies it to a clipboard. By then I have been hapilly using it for couple of months without an issue.

The fun began when I decided to try out gurk, a Signal TUI written in Rust. Those who know me, know my obsession with terminal interfaces so this was an obvious match.

One evening I was sharing a link to an image hosted on S3 when I noticed people were saying it shows 404 to them.

After pasting the link into Firefox, it worked. What is going on? I send them the link and it works now...

Time passes and I get the same responses from multiple friends - 404. After some time looking at the messages I notice a pattern - each url ends with "j".

Turns out I was copying the link with a \n at the end, which in most cases went unnoticed, but in ANSI newline delimiter is translated as "j", hence the stray jay at the end of each link.

After having a solid five minutes of immense shame I found that jq has --join-output argument, which prevents exactly my case:

     --join-output / -j:

            Like -r but jq won't print a newline after each output.

Moral of this story is that terminals are fun and shooting myself in the foot repeatedly acts as a great learning opportunity.

Some of the sources around control codes and escape sequences.

m.

联系我们 contact @ memedata.com