1

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?

C-Entropy
  • 303
  • 2
  • 9

1 Answers1

3

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).

coredump
  • 37,664
  • 5
  • 43
  • 77
  • Yes, I think this is what I need, thank you!BTW, is there any native function to change type of a file? – C-Entropy Mar 03 '21 at 15:52
  • I am not sure I understand, you can build a new pathname with a modified type, using (merge-pathnames (make-pathname :type new-type) template). For example (merge-pathnames (make-pathname :type "x") #P"a.y") is #P"a.x". But in order for this to have an effect on the file system you need to use `rename-file` probably. Also, look for the "osicat" library if you need an interface for posix stuff. – coredump Mar 03 '21 at 15:56
  • Yes, this is what I need. Thanks to you again! – C-Entropy Mar 03 '21 at 16:02