How do you load a file into racket via command line?

Michael McGuinness picture Michael McGuinness · Jun 17, 2011 · Viewed 12.3k times · Source

I have been trying to launch a racket program from the commandline (via 'racket') but have not been having success. According to the documentation (here http://docs.racket-lang.org/reference/running-sa.html#%28part._mz-cmdline%29) passing -f followed by a file should evaluate that file. However, I can't seem to get this to work. As a test, I made the following file:

;test.rkt
#lang racket
(define a 1)

Then, running it in racket (supposedly loading the file) and attempting to recall the value of a:

racket -f test.rkt -i
Welcome to Racket v5.1.1.
> a
reference to undefined identifier: a

My end goal is to be able to launch a different program from a shell script using the --main option combined with loading the definitions with -f to start up execution, just have become a bit baffled since I can't seem to get this trivial bit working.

Answer

Eli Barzilay picture Eli Barzilay · Jun 17, 2011

Removing the #lang line works, but it means that your code is no longer a module, which makes it a pretty bad idea. To start racket on a given module file, all you need is to just run racket on the file, nothing else is needed. For example, put this in test.rkt:

#lang racket/base
(printf "Hi\n")

and just run it with racket test.rkt. If you want to have command-line flags, you can use (current-command-line-arguments) to get a vector of additional command-line arguments, but there's also the racket/cmdline library that makes it much easier to have standard kinds of flag processing. Here's an example for that:

#lang racket/base

(require racket/cmdline)

(define excitedness "")
(define mode "Hi")
(command-line
  #:multi
  [("-e" "--excited") "add excitedness levels"
   (set! excitedness (string-append excitedness "!"))]
  #:once-each
  [("-b" "--bye") "turn on \"bye\" mode"
   (set! mode "Bye")])

(printf "~a~a\n" mode excitedness)

and you can now run it with racket test.rkt <flags>. See also the Racket Guide's section on scripts for making your test.rkt even easier to run.

Finally, there is the --main approach that you've seen -- to use that, your module needs to provide a main function that receives all the command-line flags as arguments. For example:

#lang racket/base
(require racket/string)
(provide main)
(define (main . xs)
  (printf "You gave me ~s flags: ~a\n"
          (length xs) (string-join xs ", ")))

and to run it:

racket -t /tmp/y -m -- foo bar baz

The flag breakdown is: -t requires your module, -m causes racket to run your main function, and -- means that the following flags are all passed to your program. You can combine the flags like so:

racket -tm- /tmp/y foo bar baz

and that would be something that you'd usually put in your script trampoline as described in that guide section.

And, of course, this is all described in great details in the reference manual.