How to provide a correct path when using run-program

268 views Asked by At

For example, I have a bunch of files name like this:

[foo

And I'm writing some code to collect and do some process to them.

(setf a (car (uiop:directory-files "/path/to/dir")));;for simplicity
                                              ;;we suppose there is only a [foo at /path/to/dir
(uiop:run-program (list "cat" (namestring a)));; cat is just an example

then it says this:

 Subprocess #<UIOP/LAUNCH-PROGRAM::PROCESS-INFO {1009C93CA3}>
 with command ("cat" "/path/to/dir/\\[foo")
 exited with error code 1

while (uiop:run-program (list "cat" "/path/to/dir/\[asd")) looks good.

I have also tried something like this:

(format NIL "~A" a)
(format NIL "~S" temp)
(princ-to-string temp)

So How can I call run-program with a rigth pathname?

1

There are 1 answers

3
coredump On BEST ANSWER

The truename is printed readably for SBCL, and SBCL allows brackets in their pathnames as wildcards so it needs to escape them in the printed representation. For example:

#P"d[0-9]"

has a pathname-name that is:

#<SB-IMPL::PATTERN "d" (:CHARACTER-SET . "0-9")>

When I test your example and inspect then pathname, I see:

A pathname.                                                                                                                                                                                                                                                             
Namestring: "/tmp/\\[a"                                                                                                                                                                                                                                                 
Host: #<SB-IMPL::UNIX-HOST {100010D983}>                                                                                                                                                                                                                                
Device: NIL                                                                                                                                                                                                                                                             
Directory: (:ABSOLUTE "tmp")                                                                                                                                                                                                                                            
Name: "[a"                                                                                                                                                                                                                                                              
Type: NIL                                                                                                                                                                                                                                                               
Version: :NEWEST                                                                                                                                                                                                                                                        
Truename: #P"/tmp/\\[a"   

So, the components are ok: the pathname name does not contain a bracket, but the pathname needs to be printed with a bracket in order to be readable.

There is no requirements for pathnames to be printed in a way that works directly as a native filename, but there is a native filename interface in SBCL, documented here.

Or, you can call (uiop:unix-namestring file).