The scriptl Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The scriptl Reference Manual

This is the scriptl Reference Manual, version 2.1, generated automatically by Declt version 2.4 "Will Decker" on Wed Jun 20 12:33:22 2018 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

ScriptL v2

There are various contortions for getting your Common Lisp started in a shell script and running some of your code. In the end, you're still falling back on writing Lisp like you're writing anything else: write, run, stop, repeat.

If only we could do this:

(defun my-command (x)
  (format t "If this were a real command, we would use ~A responsibly~%" x))

;; Make a wrapper to call this in our running Lisp!
(make-command "my-command" 'my-command)

And then:

$ my-command "foo"
If this were a real command, we would use foo responsibly.
$

Well, of course, that's exactly what ScriptL lets you do. Since this calls your running lisp, it means you're live coding your commands.

Quick Guide

You can get ScriptL from Quicklisp via (ql:quickload "scriptl"). This will load scriptl and create the scriptl command for managing scripts (see below).

First however, you must start the server. It may be convenient to create a shell script that launches your favorite CL on login and does the following:

(scriptl:start)

The scripts in examples/ require unix-options for argument parsing as well, so to run them load that system as well:

(asdf:load-system :scriptl-examples)

Now you can call things via the generated shell scripts (you might have to call them via ./[command] from the local directory):

$ funcall princ '"hello world"'
hello world
$ eval '(princ "hello world")'
hello world
$ eval '(+ 1 1)'
2
$

Alternatively, once you have something you want as a more permanent command, you can use SCRIPTL:MAKE-COMMAND as above:

(make-command COMMAND-NAME FUNCTION-NAME &optional ERROR-HANDLER)

This will make a shell script called COMMAND, probably in your home directory (or wherever you started lisp). It will call FUNCTION-NAME, with any parameters passed to the script given as strings.

Alternatively, you can use the make-command script included, which is a ScriptL wrapper for itself:

$ make-script some-command some-function [error-function]

This will make the new script in the current working directory, because wrappered calls rebind *DEFAULT-PATHNAME-DEFAULTS* for your convenience. Amusingly, you can use make-script to generate itself:

$ make-script make-script scriptl:make-script scriptl:make-script-usage

This will overwrite itself with an updated copy, assuming you're using an OS which isn't picky about such things.

scriptl and registering scripts

After installing ScriptL, the scriptl command will be created in the bin/ directory. This is part of a small API for registering, listing, and creating scripts. For instance:

$ scriptl list
Script                           Description

SCRIPTL:SCRIPTL                - ScriptL management command: scriptl
$ scriptl make SCRIPTL:SCRIPTL
$ ls
scriptl
$

This is more useful with a lot of scripts loaded. For example, after loading my personal scripts:

$ scriptl list
Script                           Description

SCRIPTL.SCRIPT.JSON:JSON       - JSON manipulation commands: json, json2yaml,
                                 sexp2json, dir2json
SCRIPTL.SCRIPT.NEW:NEW         - Template system command: new
SCRIPTL.SCRIPT.YAML:YAML       - YAML manipulation commands: yaml2json
SCRIPTL:SCRIPTL                - ScriptL management command: scriptl
$

To register scripts for this list, you should make a function which calls MAKE-COMMAND for each script you wish to create, and then call SCRIPTL:REGISTER to register this:

(defun make-my-scripts ()
  (make-command ...)
  (make-command ...))

(scriptl:register 'my-scripts 'make-my-scripts "My script commands: foo, bar, baz")
(export 'my-scripts)

Now you would see the following:

$ scriptl list
Script                           Description

MY-PACKAGE:MY-SCRIPTS          - My script commands: foo, bar, baz
SCRIPTL:SCRIPTL                - ScriptL management command: scriptl
$

Defaults and the Header

A number of useful things are set up by default:

As above, whenever a wrapper is run, ScriptL sets *DEFAULT-PATHNAME-DEFAULTS* for you, which is enough for most Lisp functions to find the right file.

However, for things like osicat, you may need to use (merge-pathnames FILENAME) to get the appropriate thing.

You may find it interesting to dispatch on the script name, which is set in SCRIPTL:*SCRIPT*. It's a pathname, so you can extract the various bits as appropriate.

Additionally, you can access the complete call information via SCRIPTL:*HEADER*, e.g.:

(defun show-header (&rest args) scriptl:*header*)

(You don't have to use &rest args; this is for demonstration.)

$ funcall show-header 1 2 3
#S(SCRIPTL:HEADER
   :VERSION 1
   :CWD #P"/path/to/current/dir/"
   :COMMAND (:FUNCALL 3 #P"./funcall")
   :FUN SHOW-HEADER
   :ARGS ("1" "2" "3")
   :ERROR-FUN NIL)
$

Most of this isn't particularly interesting or beyond what you already get, but it's there.

Readline

The v2 client adds simple support for the GNU readline library. There are two basic operations: readline PROMPT and addhistory LINE:

(defun test ()
  (format t "Type 'quit' to finish.~%")
  (loop as line = (readline "> ")
        until (string= line "quit") do
          (addhistory line)
          (format t "You typed: ~A~%" line)))

In the shell:

Type 'quit' to finish.
> foo
You typed: foo
> quit

If GNU readline support is compiled into the client (autodetected), this will have all the fancy editing features that provides, including history. If not, or if the function is not called from ScriptL, the prompt will be shown, but only basic terminal input is provided, and history is ignored.

getenv

Also included in v2 is support for remote getenv(3), allowing client-side configuration via environment variables. This is done via the scriptl:getenv function.

This will return the value of a variable on the remote side, or for functions not being called via a ScriptL command, will fall back to osicat-posix:getenv and return the environment for the running lisp.

In both cases, this returns the value of the variable as a string if set, or NIL.

I/O

The v2 protocol adds a custom client which supports standard lisp I/O operations on *standard-input* and *standard-output*. For example:

(defun test-read-line ()
  (format t "Read line: ~A~%" (read-line)))
$ echo foo | test-read-line
Read line: foo
$

Additionally, you can use read-sequence, read-byte, and read-char. The former two return octet vectors, which may be useful for processing data byte-by-byte.

Reading and writing may be interleaved as desired. Writing also supports write-sequence, write-byte, and write-char. In order to write a raw byte sequence, however, it must be specified as an array with :element-type '(unsigned-byte 8). Otherwise it will be treated as a general object, and be pretty-printed.

Results and Error Handling

When things run correctly, if there is output to *standard-output*, this is shown to the user. If there is no output, the return values are shown instead:

$ eval '(+ 2 2)'
4
$ eval '(values 1 2 3)'
(VALUES 1 2 3)
$

When things go wrong, the error condition is shown by default:

$ eval 'foo'
Error: UNBOUND-VARIABLE

The variable FOO is unbound.
$

If you want slightly more sophisticated handling, you can define an error handler when calling MAKE-SCRIPT, which will get passed the condition via HANDLER-BIND. If you handle it, return an non-NIL value. If you can't handle the condition, return NIL.

Examples

The examples/ directory has a number of examples; most of them are simply talking to the ScriptL server.

The example.lisp and test-cmd example shows how to make a more shell-scripty-feeling function with more conventional means.

Alternatively, if you look at src/make-script.lisp, you can see a (rather naïve) error handler which provides usage. MAKE-SCRIPT also handles its parameters appropriately if they're strings.

Details

This all works, of course, by making a server on a port in your Lisp and listening there. I really wanted to use Swank, but in the end the problem went from simply talking to swank to implementing READ in the shell, and that's a lot more work than just writing a new, more targeted server.

For V1, this relied on netcat. V2 presents a custom C client, which builds as part of the ASDF load operation, and supports a number of new features, such as I/O.

ScriptL initially used TCP port 4010. This is bad for a number of reasons .. each user can't have their own lisp, and anyone can access it. V2 uses Unix Domain Sockets by default, and only the owner can access it. This is restricted by file permissions.

You can still use the TCP server, by specifying (scriptl:start :internet). You can adjust the port by binding scriptl:*scriptl-port* to the desired port before doing this. This talks only to localhost. It's horribly insecure, though no moreso than swank/slime, really. If you're worried, or not the only person with access to your host, don't run it.

In theory, making this talk over an ssh tunnel would be pretty easy, but switching ports and doing the setup isn't at all nice.


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 scriptl

Author

Ryan Pavlik

License

LLGPL

Description

Scripting, Common Lisp style

Version

2.1

Dependencies
Source

scriptl.asd (file)

Components

Next: , Previous: , Up: Top   [Contents][Index]

3 Modules

Modules are listed depth-first from the system components tree.


Next: , Previous: , Up: Modules   [Contents][Index]

3.1 scriptl/bin

Parent

scriptl (system)

Location

bin/


Next: , Previous: , Up: Modules   [Contents][Index]

3.2 scriptl/src

Dependency

bin (module)

Parent

scriptl (system)

Location

src/

Components

Previous: , Up: Modules   [Contents][Index]

3.3 scriptl/src/scriptlcom

Parent

src (module)

Location

src/scriptlcom/


Next: , Previous: , Up: Top   [Contents][Index]

4 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

4.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.1 scriptl.asd

Location

scriptl.asd

Systems

scriptl (system)

Packages

scriptl.asdf

Internal Definitions

autoconf-module (class)


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.2 scriptl/src/package.lisp

Parent

src (module)

Location

src/package.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.3 scriptl/src/proto.lisp

Parent

src (module)

Location

src/proto.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.4 scriptl/src/packet-io-stream.lisp

Parent

src (module)

Location

src/packet-io-stream.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.5 scriptl/src/script-text.lisp

Parent

src (module)

Location

src/script-text.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.6 scriptl/src/make-script.lisp

Parent

src (module)

Location

src/make-script.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.7 scriptl/src/scriptl-v1.lisp

Parent

src (module)

Location

src/scriptl-v1.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.8 scriptl/src/scriptl-v2.lisp

Parent

src (module)

Location

src/scriptl-v2.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.9 scriptl/src/server.lisp

Parent

src (module)

Location

src/server.lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.10 scriptl/src/asdf-util.lisp

Parent

src (module)

Location

src/asdf-util.lisp


Previous: , Up: Lisp files   [Contents][Index]

4.1.11 scriptl/src/scriptl-cmd.lisp

Parent

src (module)

Location

src/scriptl-cmd.lisp


Next: , Previous: , Up: Top   [Contents][Index]

5 Packages

Packages are listed by definition order.


Previous: , Up: Packages   [Contents][Index]

5.1 scriptl.asdf

Source

scriptl.asd

Use List
Internal Definitions

autoconf-module (class)


Next: , Previous: , Up: Top   [Contents][Index]

6 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Previous: , Up: Definitions   [Contents][Index]

6.1 Internal definitions


Previous: , Up: Internal definitions   [Contents][Index]

6.1.1 Classes

Class: autoconf-module ()
Package

scriptl.asdf

Source

scriptl.asd

Direct superclasses

module (class)

Direct methods
  • operation-done-p (method)
  • perform (method)
Direct slots
Slot: prefix
Initargs

:prefix

Slot: configure-args
Initargs

:configure-args

Slot: test-target

Quick check to see if things are built

Initargs

:test-target


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   F   L   M   S  
Index Entry  Section

F
File, Lisp, scriptl.asd: The scriptl<dot>asd file
File, Lisp, scriptl/src/asdf-util.lisp: The scriptl/src/asdf-util<dot>lisp file
File, Lisp, scriptl/src/make-script.lisp: The scriptl/src/make-script<dot>lisp file
File, Lisp, scriptl/src/package.lisp: The scriptl/src/package<dot>lisp file
File, Lisp, scriptl/src/packet-io-stream.lisp: The scriptl/src/packet-io-stream<dot>lisp file
File, Lisp, scriptl/src/proto.lisp: The scriptl/src/proto<dot>lisp file
File, Lisp, scriptl/src/script-text.lisp: The scriptl/src/script-text<dot>lisp file
File, Lisp, scriptl/src/scriptl-cmd.lisp: The scriptl/src/scriptl-cmd<dot>lisp file
File, Lisp, scriptl/src/scriptl-v1.lisp: The scriptl/src/scriptl-v1<dot>lisp file
File, Lisp, scriptl/src/scriptl-v2.lisp: The scriptl/src/scriptl-v2<dot>lisp file
File, Lisp, scriptl/src/server.lisp: The scriptl/src/server<dot>lisp file

L
Lisp File, scriptl.asd: The scriptl<dot>asd file
Lisp File, scriptl/src/asdf-util.lisp: The scriptl/src/asdf-util<dot>lisp file
Lisp File, scriptl/src/make-script.lisp: The scriptl/src/make-script<dot>lisp file
Lisp File, scriptl/src/package.lisp: The scriptl/src/package<dot>lisp file
Lisp File, scriptl/src/packet-io-stream.lisp: The scriptl/src/packet-io-stream<dot>lisp file
Lisp File, scriptl/src/proto.lisp: The scriptl/src/proto<dot>lisp file
Lisp File, scriptl/src/script-text.lisp: The scriptl/src/script-text<dot>lisp file
Lisp File, scriptl/src/scriptl-cmd.lisp: The scriptl/src/scriptl-cmd<dot>lisp file
Lisp File, scriptl/src/scriptl-v1.lisp: The scriptl/src/scriptl-v1<dot>lisp file
Lisp File, scriptl/src/scriptl-v2.lisp: The scriptl/src/scriptl-v2<dot>lisp file
Lisp File, scriptl/src/server.lisp: The scriptl/src/server<dot>lisp file

M
Module, scriptl/bin: The scriptl/bin module
Module, scriptl/src: The scriptl/src module
Module, scriptl/src/scriptlcom: The scriptl/src/scriptlcom module

S
scriptl.asd: The scriptl<dot>asd file
scriptl/bin: The scriptl/bin module
scriptl/src: The scriptl/src module
scriptl/src/asdf-util.lisp: The scriptl/src/asdf-util<dot>lisp file
scriptl/src/make-script.lisp: The scriptl/src/make-script<dot>lisp file
scriptl/src/package.lisp: The scriptl/src/package<dot>lisp file
scriptl/src/packet-io-stream.lisp: The scriptl/src/packet-io-stream<dot>lisp file
scriptl/src/proto.lisp: The scriptl/src/proto<dot>lisp file
scriptl/src/script-text.lisp: The scriptl/src/script-text<dot>lisp file
scriptl/src/scriptl-cmd.lisp: The scriptl/src/scriptl-cmd<dot>lisp file
scriptl/src/scriptl-v1.lisp: The scriptl/src/scriptl-v1<dot>lisp file
scriptl/src/scriptl-v2.lisp: The scriptl/src/scriptl-v2<dot>lisp file
scriptl/src/scriptlcom: The scriptl/src/scriptlcom module
scriptl/src/server.lisp: The scriptl/src/server<dot>lisp file

Jump to:   F   L   M   S  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions


Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   C   P   S   T  
Index Entry  Section

C
configure-args: Internal classes

P
prefix: Internal classes

S
Slot, configure-args: Internal classes
Slot, prefix: Internal classes
Slot, test-target: Internal classes

T
test-target: Internal classes

Jump to:   C   P   S   T  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   A   C   P   S  
Index Entry  Section

A
autoconf-module: Internal classes

C
Class, autoconf-module: Internal classes

P
Package, scriptl.asdf: The scriptl<dot>asdf package

S
scriptl: The scriptl system
scriptl.asdf: The scriptl<dot>asdf package
System, scriptl: The scriptl system

Jump to:   A   C   P   S