21.2 Scripts

► |  | The Racket Guide

1 | Welcome to Racket
2 | Racket Essentials
3 | Built-In Datatypes
4 | Expressions and Definitions
5 | Programmer-Defined Datatypes
6 | Modules
7 | Contracts
8 | Input and Output
9 | Regular Expressions
10 | Exceptions and Control
11 | Iterations and Comprehensions
12 | Pattern Matching
13 | Classes and Objects
14 | Units
15 | Reflection and Dynamic Evaluation
16 | Macros
17 | Creating Languages
18 | Concurrency and Synchronization
19 | Performance
20 | Parallelism
21 | Running and Creating Executables
22 | More Libraries
23 | Dialects of Racket and Scheme
24 | Command-Line Tools and Your Editor of Choice
| Bibliography
| Index

▼ | 21 | Running and Creating Executables

21.1 | Running racket and gracket
21.2 | Scripts
21.3 | Creating Stand-Alone Executables

► | 21.2 | Scripts

21.2.1 | Unix Scripts
21.2.2 | Windows Batch Files

On this page:

21.2.1`` Unix Scripts
21.2.2`` Windows Batch Files

top contents ← prev up next →

#### 21.2`` Scripts🔗ℹ

Racket files can be turned into executable scripts on Unix and Mac OS. On Windows, a compatibility layer like Cygwin support the same kind of scripts, or scripts can be implemented as batch files.

##### 21.2.1`` Unix Scripts🔗ℹ

In a Unix environment (including Linux and Mac OS), a Racket file can be turned into an executable script using the shell’s #! convention. The first two characters of the file must be #!; the next character must be either a space or /, and the remainder of the first line must be a command to execute the script. For some platforms, the total length of the first line is restricted to 32 characters, and sometimes the space is required.

> > > Use #lang racket/base instead of #lang racket to produce scripts with a faster startup time.

The simplest script format uses an absolute path to a racket executable followed by a module declaration. For example, if racket is installed in "/usr/local/bin", then a file containing the following text acts as a “hello world” script:

#! /usr/local/bin/racket
#lang racket/base
"Hello, world!"

In particular, if the above is put into a file "hello" and the file is made executable (e.g., with chmod a+x hello), then typing ./hello at the shell prompt produces the output "Hello, world!".

The above script works because the operating system automatically puts the path to the script as the argument to the program started by the #! line, and because racket treats a single non-flag argument as a file containing a module to run.

Instead of specifying a complete path to the racket executable, a popular alternative is to require that racket is in the user’s command path, and then “trampoline” using /usr/bin/env:

#! /usr/bin/env racket
#lang racket/base
"Hello, world!"

In either case, command-line arguments to a script are available via current-command-line-arguments:

#! /usr/bin/env racket
#lang racket/base
(printf "Given arguments: ~s\n"
(current-command-line-arguments))

If the name of the script is needed, it is available via (find-system-path 'run-file), instead of via (current-command-line-arguments).

Usually, the best way to handle command-line arguments is to parse them using the command-line form provided by racket. The command-line form extracts command-line arguments from (current-command-line-arguments) by default:

#! /usr/bin/env racket
#lang racket
(define verbose? (make-parameter #f))
(define greeting
(command-line
#:once-each
[("-v") "Verbose mode" (verbose? #t)]
#:args
(str) str))
(printf "~a~a\n"
greeting
(if (verbose?) " to you, too!" ""))

Try running the above script with the --help flag to see what command-line arguments are allowed by the script.

An even more general trampoline uses /bin/sh plus some lines that are comments in one language and expressions in the other. This trampoline is more complicated, but it provides more control over command-line arguments to racket:

#! /bin/sh
#|
exec racket -e '(printf "Running...\n")' -u "$0" ${1+"$@"}
|#
#lang racket/base
(printf "The above line of output had been produced via\n")
(printf "a use of the `-e' flag.\n")
(printf "Given arguments: ~s\n"
(current-command-line-arguments))

Note that #! starts a line comment in Racket, and #|...|# forms a block comment. Meanwhile, # also starts a shell-script comment, while exec racket aborts the shell script to start racket. That way, the script file turns out to be valid input to both /bin/sh and racket.

##### 21.2.2`` Windows Batch Files🔗ℹ

A similar trick can be used to write Racket code in Windows .bat batch files:

; @echo off
; Racket.exe "%~f0" %*
; exit /b
#lang racket/base
"Hello, world!"

Newer versions of Windows include the PowerShell scripting language. Using Racket through a PowerShell script is a little different than using it in a batch file. PowerShell scripts use a .ps1 extension:

; Racket.exe (Resolve-Path $PSCommandPath) $args
; Exit
#lang racket/base
"Hello, world!"

top contents ← prev up next →