You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向Slime REPL输入缓冲区写入字符串?Common Lisp Shell问题

问题:Common Lisp Shell实现元命令占位符输入编辑功能

需求说明

我正在用Common Lisp编写一款Shell程序,读取用户输入的命令并执行后返回输出。当用户输入元命令时,希望在输入缓冲区写入占位符,让用户可直接按回车执行该命令,或像编辑自身输入内容一样编辑它。

当前实现代码

(defun eval-print (command-executor command)
  (format t "~a~%" (funcall command-executor command)))

(defun cmd-exec-local (command)
  "Execute a command in the local shell"
  (trim (uiop:run-program command :output :string)))

(defun shell (command-executor &optional placeholder)
  "Simulate a REPL"
  (progn
    (if placeholder
        (format t ">>> ~a" placeholder) ; 这里尝试显示占位符
        (format t ">>> "))
    (let ((command (read-line))) ; 检查用户是否输入元命令,否则执行输入内容
      (cond ((string= "@exit" command) (format t "Bye!~%")) ; 退出Shell
            ((string= "@bashrev" command) (shell command-executor *bash-rev*)) ; Bash反向Shell
            ((string= "@info" command) (shell command-executor "whoami")) ; 系统信息
            (t (eval-print command-executor command) (shell command-executor)))))) ; 执行命令

问题现象

运行时占位符仅输出到标准输出,无法被read-line读取,按回车也不会执行;手动输入的命令则正常:

PENTESTING> (shell #'cmd-exec-local)
>>> @info
>>> whoami ; 这只是输出到标准输出,按回车无任何执行

>>> whoami ; 用户手动输入的内容,按回车可正常得到结果
kali
>>> @exit
Bye!

解决方案

问题核心是format t仅将文本输出到终端,并未写入输入缓冲区,read-line只会读取用户实际输入的内容。要实现编辑占位符的功能,需使用终端控制库操作输入行,推荐使用cl-readline(Common Lisp版GNU Readline绑定)。

步骤1:安装cl-readline

通过Quicklisp安装:

(ql:quickload :cl-readline)

步骤2:修改代码使用cl-readline替代read-line

利用rl:read-line函数,它支持预填充初始文本(占位符),用户可直接编辑或按回车执行:

(defun eval-print (command-executor command)
  (format t "~a~%" (funcall command-executor command)))

(defun cmd-exec-local (command)
  "Execute a command in the local shell"
  (trim (uiop:run-program command :output :string)))

(defun shell (command-executor &optional placeholder)
  "Simulate a REPL with editable placeholder support"
  (let ((command (rl:read-line :prompt (if placeholder ">>> " ">>> ")
                               :initial-text (or placeholder ""))))
    (cond ((string= "@exit" command) (format t "Bye!~%"))
          ((string= "@bashrev" command) (shell command-executor *bash-rev*))
          ((string= "@info" command) (shell command-executor "whoami"))
          (t (eval-print command-executor command)
             (shell command-executor)))))

说明

  • rl:read-line的:initial-text参数会将占位符文本填充到输入行,用户可直接编辑或按回车提交。
  • 该方案依赖GNU Readline的终端控制能力,能实现类似Bash的输入编辑体验,包括光标移动、文本修改等。
  • 若无需完整Readline功能,直接操作终端输入缓冲区需依赖系统特定API(如Unix的tcsetattr),实现复杂且跨平台性差,使用cl-readline是更简洁的选择。

内容的提问来源于stack exchange,提问作者Antonio Solana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:20:30