在交互模式下 shell 到 运行 Racket 程序的脚本出错

Error with shell script to run Racket program in interactive mode

我制作了一个 shell 脚本,它接收球拍文件作为参数并将其用于 运行 下面的命令以执行文件并保持交互模式。

racket -i -e '(enter! "filename.rkt")'

问题是,当我 运行 脚本执行上面的命令时没有最后一个单引号,这会生成一条错误消息。

我试过在命令末尾(脚本内)放置更多字符,看看它是否只是忽略了最后一个字符,但它没有用。

这是我的脚本:

# rkt.sh

if [ "$#" -ne 1 ]; then
    echo "Not enough parameters!"
else
    option=\''(enter! "''")'\'
    racket -i -e "$path"
fi

运行执行命令后:

rkt test.rkt

这是球拍程序显示的错误:

Welcome to Racket v7.0.
'(enter! "test.rkt")
string::21: read-syntax: expected an element for quoting "'", found end-of-file
  context...:
   reader-error12
   read-undotted
   read-syntax

但是当我回显脚本的变量 option 时,它会打印所需的结果:

'(enter! "test.rkt")'

Scheme 实现中的单引号和类似 Racket 的后代用于文字数据,您不将它们配对。

出现错误消息是因为它读取了 '(enter! "test.rkt") 并将其计算为 (enter! "test.rkt"),尽管您使用的是标准 Racket 打印模式,它不显示该值,而是一个计算为的值那个值。因此 '(enter! "test.rkt")。在此之后,它读取了 ' 但不是获取引用的内容,而是数据到此结束。 'x 有效 ' 无效。

我猜这就是你想要的:

#/bin/sh

if [ "$#" -ne 1 ]; then
    echo "Not enough parameters!"
else
    option="(enter! \"\")"
    racket -i -e "$option"
fi

当您让它加载文件时,它可能创建的定义似乎不可用。因此,在它完成它的事情之后处于交互模式并不能提供太多的功能。

这是一种无需通过 Bash 即可在 Racket 中编写我认为您心中所想的方法。只是 chmod +x 文件。

#!/usr/bin/env racket
#lang racket/base

(require racket/cmdline)

(define file
  (command-line
   #:usage-help "start a Racket REPL inside the module <file>"
   #:args (file)
   file))

(void (write-string (banner)))

(define ns (make-base-namespace))
(parameterize ([current-namespace ns])
  (eval '(require racket/init racket/interactive))
  (eval `(enter! ,file))
  (read-eval-print-loop))