common-lispsbcl

Why read-line reads to symbol (instead of string) in sbcl compiled executable?


Just as an exercise, I am trying to use CL to filter output from the bash locate command by directories (i.e. list only files that are directories). For that, I created a file named dirfilter.lisp with the following code:

#!/usr/bin/env -S sbcl --script

(let (line)
  (loop while (setq line (read-line))
    when (not (pathname-name (probe-file line)))
    do (princ line) (terpri)))

It works fine when using it as follows locate -i hello | ./dirfilter.lisp.

However, also just as an exercise, I have created a standalone executable by removing the shebang line and then using the following lines from the SBCL repl:

(load (compile-file "dirfilter.lisp"))

(save-lisp-and-die "dirfilter" :executable t)

Now, however, when trying to use the standalone executable as follows locate -i hello | ./dirfilter I get the following error:

debugger invoked on a UNBOUND-VARIABLE @52BBE314 in thread
#<THREAD tid=203029 "main thread" RUNNING {1001448003}>:
  The variable /HOME/DALANICOLAI/HELLO.PNG is unbound.

As far as I understand the error, read-line in the executable does not read the input as a string but as a symbol.

What is happening here, and how to fix it?


Solution

  • You've misdiagnosed the problem. You need to

    See the manual.

    Without doing this, what it's doing is just starting a REPL which then tries to read a pathname as a symbol and then evaluate that symbol.