微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 SBCL Common Lisp 中执行“docker run”

如何解决在 SBCL Common Lisp 中执行“docker run”

我正在尝试在我的 lisp 程序中运行一个函数。它是一个连接到 IRC 通道的机器人,您可以使用特殊命令查询机器人以评估简单的 lisp 命令。因为从互联网上的人那里执行任意代码是非常危险的,所以我希望实际的评估发生在一个运行 docker 的虚拟机中,用于机器人获得的每个评估查询

我的函数如下所示:

(defun run-command (cmd)
  (uiop:run-program (list "docker" "run" "--rm" "-it" "my/docker" "sbcl" "--noinform" "--no-sysinit" "--no-userinit" "--noprint" "--disable-debugger" "--eval" (string-trim '(#\^M) (format nil "~A" cmd))) "--eval" "'(quit)'") :output '(:string :stripped t))

这个函数背后的想法是启动一个包含 SBCL 的 docker,通过 SBCL --eval 运行命令并将其打印到 docker std-out。而这个打印出来的字符串应该是 run-command 的结果。

如果我打电话

docker run --rm -it my/docker sbcl --noinform --no-sysinit --no-userinit --noprint --disable-debugger --eval "(print (+ 2 3))" --eval "(quit)"

在我的命令行上,我只得到 5,这正是我想要的。

但是如果我在 lisp 中运行相同的命令,我会得到 uiop:run-program 函数

Subprocess #<UIOP/LAUNCH-PROGRAM::PROCESS-INFO {1004FC3923}>
 with command ("docker" "run" "--rm" "-it"
               "my/docker" "sbcl" "--noinform"
               "--no-sysinit" "--no-userinit" "--noprint"
               "--disable-debugger" "--eval" "(+ 2 3)")

作为错误消息,这意味着该过程以某种方式失败。但我不知道这里到底有什么问题。如果我只是执行例如“ls”,我会得到输出,所以该函数似乎可以正常工作。

关于uiop:run-program,我是否需要一些特殊知识,还是我做错了什么?

提前致谢。

编辑:所以事实证明 -it 标志导致了问题。移除标志后,出现新错误。现在机器人没有执行 docker 的权限。有没有办法在不授予它 sudo 权限的情况下授予它权限?

解决方法

这里(或 SBCL)调用 docker 的方式可能有问题。要获取错误消息,请使用 uiop:run-program 参数调用 :error-output :string,然后选择 continue 重新启动以实际终止执行并打印错误输出(如果您从 SLIME 运行或其他一些 REPL)。如果您在非交互式环境中调用它,则可以将调用包装在处理程序绑定中:

(handler-bind ((uiop/run-program:subprocess-error
                 (lambda (e) (invoke-restart (find-restart 'continue)))))
  (run-command ...))
,

结果证明 -it 确实引起了麻烦。删除它并将正确的权限提升到机器人后,一切正常。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。