【问题标题】:Common lisp: run shell command containing the string "\n"Common lisp:运行包含字符串“\n”的shell命令
【发布时间】:2016-12-24 18:32:48
【问题描述】:

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

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

并试图让它返回类似的东西

"one two"

而它返回的是

"onentwo "

我愿意使用与 trivial-shell 不同的东西(我尝试过低级 shell,但遇到了同样的问题)

在 64 位 Gentoo Linux 上使用 SBCL 1.1.18

【问题讨论】:

  • 反斜杠转义下一个字符。如果要在字符串中使用反斜杠字符,则必须使用另一个反斜杠 "\\n" 对其进行转义。
  • 字符串中的反斜杠必须反斜杠
  • 也不行,结果是一样的。三个反斜杠也是一样的。四个反斜杠在我在问题中给出的示例中有效,但在实际代码中不起作用 - 我将更新问题以反映这一点。
  • 命令中的字符串也缺少引号。

标签: linux shell common-lisp newline sbcl


【解决方案1】:

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

(print "one
two")

您还可以将换行符强制转换为字符串:

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

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

(print "\\n")

那么,为什么需要 4 个反斜杠呢?

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

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

知道了这一点,您可能需要考虑到与 bourne 兼容的 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))))

【讨论】:

    【解决方案2】:

    通过使用四个反斜杠而不是一个来解决它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多