惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
GbyAI
GbyAI
爱范儿
爱范儿
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
M
MIT News - Artificial intelligence
量子位
宝玉的分享
宝玉的分享
MongoDB | Blog
MongoDB | Blog
V
Visual Studio Blog
罗磊的独立博客
F
Fortinet All Blogs
美团技术团队
博客园_首页
博客园 - 【当耐特】
L
LangChain Blog
月光博客
月光博客
腾讯CDC
The Cloudflare Blog
D
Docker
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

依云's Blog

Wayfire支持不缩放Xwayland啦 - 依云's Blog 使用wayvnc远程访问无头Wayfire会话 - 依云's Blog pacfiles: 高速的 pacman -F 替代品 用 Android 手机当电脑的话筒 - 依云's Blog 使用 ffmpeg 对音频文件进行响度归一化 - 依云's Blog 使用 nftables 屏蔽大量 IP - 依云's Blog YubiKey 初体验 - 依云's Blog fcitx5 码表同步方案 - 依云's Blog 我正在使用的火狐扩展(2024年版) - 依云's Blog 使用 PipeWire 实现自动应用均衡器 如果你发现你的 OOM Killer 在乱杀进程 使用 atuin 管理 shell 命令历史 btrfs 元数据满了怎么办 btrfs 翻车记 在 nspawn 里运行 docker Linux 上的字体配置与故障排除 新的 PaddleOCR 部署方案 使用 EasyEffects 调整 Bose 音箱的体验 让离线软件真正离线 我所讨厌的网页行为 tmux 状态栏优化 Google Chrome 中的字体设置 从 getmail6 到 offlineimap 微信消息通知的困扰 Qt 的字体渲染问题 Wayfire 迁移进展(四):不那么 high 的 DPI Wayfire 迁移进展(二):Xwayland HiDPI 以及 waybar Wayfire 迁移进展 不同情况下的图形效果 Wayland 初体验
弄了个支持 readline 的 MongoDB shell
依云 · 2011-11-28 · via 依云's Blog

不知道怎么搞的,新版 MongoDB 自带的 mongo shell 现在不支持 readline,而且使用一个极简到工作不正常的 linenoise。编译时加上 readline 也没用。虽然内建了简单的历史记录和补全,可是历史记录不能搜索,补全只能像 Vim 命令行默认的那样一个一个切换不能像 bash/zsh 那样全部列出来。这些还不是最令人郁闷的。最让我受不了的问题和十年前的 DOS 版 WPS 里遇到的差不多——当年的 WPS 里删汉字一次只删一半,现在的 mongo shell 里删汉字一次只删三分之一!而且光标定位是错的,按字节算的!

于是乎拿 Python 写了一个 shell。不愧是 Python,内置的东西真不错,不到100行就写好了。不过用到了自己另外的库函数,另外用到了自己的 colorless 程序来高亮显示查询结果。如果不想要 pygments 这个依赖的话,可以用 less 程序代替。以下贴个无高亮版的,高亮版的见 github

#!/usr/bin/env python3
# vim:fileencoding=utf-8

import sys
import os
from pprint import pprint
import subprocess

from pymongo import Connection
import pymongo.cursor

# 这个模块位于 github 上的 winterpy 仓库的 pylib/cli.py
from cli import repl

import locale
locale.setlocale(locale.LC_ALL, '')
del locale

host = 'localhost'
port = 27017
db = 'test'

def displayfunc(value):
  if isinstance(value, pymongo.cursor.Cursor):
    p = subprocess.Popen(['less', '-RFX'], stdin=subprocess.PIPE,
                        universal_newlines=True)
    pprint(list(value), stream=p.stdin)
    p.stdin.close()
    p.wait()
  else:
    pprint(value)

def main():
  global db
  conn = Connection(host=host, port=port)
  db = conn[db]

  v = globals().copy()
  v.update(locals())
  del v['repl'], v['argv'], v['main'], v['v'], v['host'], v['port']
  del v['displayfunc'], v['subprocess']
  del v['__name__'], v['__cached__'], v['__doc__'], v['__file__'], v['__package__']
  sys.displayhook = displayfunc

  repl(
    v, os.path.expanduser('~/.mongo_history'),
    banner = 'Python MongoDB console',
  )

if __name__ == '__main__':
  argv = sys.argv
  if len(argv) == 2:
    if '/' in argv[1]:
      host, db = argv[1].split('/', 1)
    if ':' in host:
      host, port = host.split(':', 1)
  elif len(argv) == 1:
    pass
  else:
    sys.exit('argument error')

  main()