Common lisp: 运行 shell 命令包含字符串 "\n"

Common lisp: run shell command containing the string "\n"

我正在尝试 运行 一些可以简化为

的东西

(trivial-shell:shell-command (concatenate 'string "echo -e " "one" "\n" "two"))

并试图将它变成 return 类似

"one two"

而 return 是

"onentwo "

我愿意使用与 trivial-shell 不同的东西(我试过 inferior-shell,但它有同样的问题)

在 64 位 Gentoo 上使用 SBCL 1.1.18 Linux

通过使用四个反斜杠而不是一个反斜杠解决了这个问题。

输出换行符的最简单方法是在字符串中添加一个换行符:

(print "one
two")

你也可以将换行符强制转换为字符串:

(concatenate 'string "one" (string #\newline) "two")

您不能在字符串中使用 \n 来插入换行符:反斜杠仅用于转义字符串中的双引号(例如 "\"")。必要时,它也用于转义实际的反斜杠字符。 所以如果你想打印一个反斜杠后跟n,你需要转义反斜杠:

(print "\n")

但是,为什么需要 4 个反斜杠?

因为 trivial-shell:shell-command 调用 *bourne-compatible-shell* 给出的 shell,并给它一个字符串形式的命令。因此,您的字符串也可能受制于 shell 转义规则。

(trivial-shell:shell-command "echo -e one \\n two")

知道这一点后,您可能需要考虑以下事实:与伯恩兼容的 shell 具有单引号,不需要在其中转义字符。以下按预期工作:

(trivial-shell:shell-command "echo 'one 
two'")

请注意,trivial-shell:*bourne-compatible-shell* 的默认值为 "/bin/sh",据我所知,它无法识别 echo-e 选项。您可能已经知道这一点,但您可能想使用不同的 shell。这是一个调用 echo 并在参数之间换行的程序:

(defun echo-args (&rest args)
  (let ((trivial-shell:*bourne-compatible-shell* #P"/bin/bash"))
    (trivial-shell:shell-command
     (format nil "echo -e '~{~A~^~%~}'" args))))