2

I want to pass sbcl a string as a single argument using a bashcript but sbcl splits the string into a list.

bashscript

#!/bin/bash

    sbcl --noinform --eval "(progn (FORMAT t \"~{~a~%~}\" sb-ext:*posix-argv*)(eval (read-from-string (second sb-ext:*posix-argv*))))" $1

execution:

>sh bashsrcipt.bs "\"(FORMAT t \"YEAH\")\""
sbcl
"(FORMAT
t
"YEAH")"

debugger invoked on a END-OF-FILE in thread
#<THREAD "initial thread" RUNNING {1002999833}>:
  end of file on #<SB-IMPL::STRING-INPUT-STREAM {100443F523}>

But the result should have been

>sh bashcript.bs "\"(FORMAT t \"YEAH~%\"\")"
sbcl
"(FORMAT t \"YEAH\")"
YEAH

The manual does not mention such behavior.

4

2 回答 2

8

You need to quote $1 in your script, I think:

sbcl --noinform --eval "..." "$1"

(argument to --eval elided for clarity)

于 2012-08-22T12:45:47.487 回答
2

$1 should be enclosed with "" if you want it to be passed as a single argument when it contains whitespace characters:

#!/bin/bash
sbcl --noinform --eval "(progn (format t \"~{~a~%~}\" sb-ext:*posix-argv*) (eval (read-from-string (second sb-ext:*posix-argv*))))" "$1"

Moreover, \" before and after (FORMAT ...) in the command-line argument should be removed, which is making read-from-string return a string, not a list, that evaluates to itself. That is, the two \"s are preventing FORMAT in the argument from being executed:

$ sh bashscript.bs "\"(FORMAT t \"YEAH~%\")\""
sbcl
"(FORMAT t "YEAH~%")"
$ sh bashscript.bs "(FORMAT t \"YEAH~%\")"
sbcl
(FORMAT t "YEAH~%")
YEAH
于 2012-08-22T12:56:16.287 回答