How to execute a common lisp text file (clozure cl)? - common-lisp

I am a beginner at Lisp, having only used DrRacket for some dabbling in Racket/Scheme. I have had much trouble figuring out how to run a .lisp file with Clozure CL for Windows. I tried running a .lisp file in SBCL on Ubuntu (running on virtualbox) without success as well.
I should mention that I've looked into the related questions about running files but I wasn't able to see any direct solution. Some are using .bat files, some are "creating applications" with Clozure CL's image (or something along those lines).
For SBCL in Ubuntu, I've tried:
sbcl lisptest.lisp \ The python/forth way.
(load "lisptest.lisp")
(load lisptest.lisp)
(--load lisptest.lisp)
:cd C:\Temp
(:cd C:\Temp)
and more.
I also tried to run it from notepad++:
cmd /k C:\Temp\ccl-1.11-windows\ccl\wx86cl64.exe "$(FULL_CURRENT_PATH)"
which is how I usually execute python files, but this method hasn't been successful.
**I will definitely start learning to use Emacs and Slime (Emacs is the obvious choice for lisp). But for the sake of knowledge, I would appreciate some tips on the alternative, basic-text-editor way of getting something trivial like "hello world" to print without my typing it explicity into the REPL and instead interpreting (or compiling) a text file with the instruction.
Thanks for your help.

Typically programs have help - did you look at that?
SBCL, Ubuntu, from the shell:
A Common Lisp file:
$ cat test.lisp
(format t "Hello World~%~%")
SBCL shows help:
$ sbcl --help
Usage: sbcl [runtime-options] [toplevel-options] [user-options]
Common runtime options:
--help Print this message and exit.
--version Print version information and exit.
--core <filename> Use the specified core file instead of the default.
--dynamic-space-size <MiB> Size of reserved dynamic space in megabytes.
--control-stack-size <MiB> Size of reserved control stack in megabytes.
Common toplevel options:
--sysinit <filename> System-wide init-file to use instead of default.
--userinit <filename> Per-user init-file to use instead of default.
--no-sysinit Inhibit processing of any system-wide init-file.
--no-userinit Inhibit processing of any per-user init-file.
--disable-debugger Invoke sb-ext:disable-debugger.
--noprint Run a Read-Eval Loop without printing results.
--script [<filename>] Skip #! line, disable debugger, avoid verbosity.
--quit Exit with code 0 after option processing.
--non-interactive Sets both --quit and --disable-debugger.
Common toplevel options that are processed in order:
--eval <form> Form to eval when processing this option.
--load <filename> File to load when processing this option.
User options are not processed by SBCL. All runtime options must
appear before toplevel options, and all toplevel options must
appear before user options.
For more information please refer to the SBCL User Manual, which
should be installed along with SBCL, and is also available from the
website <http://www.sbcl.org/>.
Using the script option from above:
$ sbcl --script test.lisp
Hello World
The same for Clozure CL
$ ccl --help
usage: ccl <options>
where <options> are one or more of:
-h, --help : this text
-V, --version : print (LISP-IMPLEMENTATION-VERSION) and exit
-K, --terminal-encoding : specify character encoding to use for *TERMINAL-IO*
-n, --no-init : suppress loading of init file
-e, --eval : evaluate <form> (may need to quote <form> in shell)
-l, --load : load <file>
-T, --set-lisp-heap-gc-threshold : set lisp-heap-gc-threshold to <n>
-Q, --quiet : if --batch, also suppress printing of heralds, prompts
-R, --heap-reserve <n>: reserve <n> (default: 1610612736)
bytes for heap expansion
-S, --stack-size <n>: set size of initial thread's control stack to <n>
-Z, --thread-stack-size <n>: set default size of first (listener) thread's stacks based on <n>
-b, --batch: exit when EOF on *STANDARD-INPUT*
--no-sigtrap : obscure option for running under GDB
--debug : try to ensure that kernel debugger uses a TTY for I/O
-I, --image-name <image-name>
and <image-name> defaults to ccl.image
Any arguments following the pseudoargument "--" are
not processed and are available to the application as
the value of CCL:*UNPROCESSED-COMMAND-LINE-ARGUMENTS* .
Using the load option from above
$ ccl --load test.lisp --eval '(quit)'
Hello World

 
Try
C:/path/to/ccl -l lisptest.lisp
This should work the same as
(load "lisptest.lisp")
If you can let us know specifically how that fails, we can be of more help.

Related

Why the shell knows the interpreter specified in the shebang-line of a file without read permission

I am trying to learn shell on Linux,
but I've got a problem which seems confusing.
My environment is:
OS: Manjaro 21.2.6 Qonos
Kernel: x86_64 Linux 5.15.38-1-MANJARO
Shell: zsh 5.8.1 (x86_64-pc-linux-gnu)
The problem is:
I created a file named foo, and echoed #\!/bin/sh to it, and the permission of file foo has been modified to 100 by using chmod.
The file foo doesn't have the read or write permission indeed, that's for true,
but when I executed the command ./foo, I got the error /bin/sh: ./foo: permission denied.
So why the Shell knows what the shebang in the file foo is without the read permission ???
If anyone of you can proide any suggesstions, I will be really thankful !
behavior-example
So why the Shell knows what the shebang in the file foo is without the read permission ???
It is not the shell that reads the shebang line but the OS/kernel.
A shell script can be executed in the same way as a compiled program. The process uses a function of the exec* family and passes ./foo as the program to execute. These functions are based on system calls.
The OS/kernel then detects if the file is a compiled program which can be executed directly or a script file which must be passed to an interpreter. If the file contains a shebang line, the OS will execute the specified interpreter, which does not have to be a shell, otherwise it will run the default shell. The script file is passed as an argument to the interpreter.
The shell is running with normal user permissions and will get an error when it tries to open the script file.
You can find some information about executiong scripts in the POSIX specification of the exec function family or in the Linux manual page for execve. Search for the word interpreter. You could check the Linux kernel source code for more details.
You get this error because the script itself do not have execution or read permission. To run script in shell (on your way) you need to have read and execute permissions:
chmod 500 foo
./foo
the other way to run the script is:
sh foo
and you do not need execution permission in this case. For the record the standard way is to use construction like:
#!/bin/sh
You do not need to escape exclamation mark

How to use additional flags when creating lisp script file to start from console

I want to create a .lisp file which I can start as script, i.e., with a leading #!/bin/usr/sbcl --script. This works just fine.
File:
#!/usr/bin/sbcl --script
(format t "test~%")
Output:
$> ./test.lisp
test
However, I also need to adjust the dynamic space size for that particular script to work. But this somehow prevents the --script flag from working
File:
#!/usr/bin/sbcl --dynamic-space-size 12000 --script
(format t "test~%")
Output:
$> ./test.lisp
This is SBCL 1.4.5.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
*
How can I increase the dynamic space size while keeping the convenience of starting the lisp program/script from the command prompt?
This is a general limitation of shebang lines and not SBCL specific.
Newer env versions (in GNU — FreeBSD has had this a bit longer) understand a -S option to split the argument:
https://www.gnu.org/software/coreutils/manual/html_node/env-invocation.html#g_t_002dS_002f_002d_002dsplit_002dstring-usage-in-scripts
#!/usr/bin/env -S sbcl --dynamic-space-size 9000 --script
Apparently the #! considers everything following the command as a single string and thus --dynamic-space-size 12000 --script is treated as one and not as a parameter and a flag.
My current solution is to create an additional .sh file:
#!/bin/bash
sbcl --dynamic-space-size 12000 --script ./test.lisp $#
However, this has the obvious downside that the script needs to be started from the same directory as the .lips file. Consequently, I am still looking for the 'perfect' solution and this is rather a stop-gap.

How to fix asdf error when using buildapp on a quicklisp project

I've been making my first quicklisp project lately and I wanted to share it. I've put it on github, but not everyone has emacs + slime + quicklisp installed so I wanted to make an executable I could put with the code.
To do this I'm using buildapp and following the steps laid out in this stackoverflow answer.
$ sbcl --no-userinit --no-sysinit --non-interactive \
--load ~/quicklisp/setup.lisp \
--eval '(ql:quickload "ltk-colorpicker")' \
--eval '(ql:write-asdf-manifest-file "quicklisp-manifest.txt")'
$ buildapp --output out \
--manifest-file quicklisp-manifest.txt \
--load-system ltk-colorpicker \
--entry colorpicker
After running those commands I get the following error:
Fatal INPUT-ERROR-IN-LOAD:
READ error during LOAD:
The symbol "*SYSTEM-DEFINITION-SEARCH-FUNCTIONS*" is not external in the ASDF/FIND-SYSTEM package.
Line: 16, Column: 90, File-Position: 15267
Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /home/nathan/quicklisp/local-projects/ltk-colorpicker/dumper-2SKVI5f7.lisp" {1001B70F83}>
The main problem here is that I don't even have a clue at how to begin to fix it. I've seen this gibhub issue, but that had to do with problems with Homebrew and it never even mentions buildapp. It's all very confusing. And I hope I could get some help.
Thanks in advance for any answers.
I can reproduce the error. As suggested in the comments, you can build an up-to-date version of buildapp as follows:
$ sbcl
* (ql:quickload :buildapp)
...
* (buildapp:build-buildapp
(merge-pathnames "bin/buildapp" (user-homedir-pathname)))
This build $HOME/bin/buildapp. When I use the new binary, there is no error anymore.
You can also avoid generating an executable (that can end up being outdated) by systematically calling the buildapp::main function from Common Lisp; you will then always have the version that corresponds to the current release of quicklisp:
* (buildapp::main
'("BUILDAPP" ;; argv[0] must exist but the value is not important
"--manifest-file" "/tmp/quicklisp-manifest.txt"
"--load-system" "drakma" "--output" "/tmp/test"))
Some extra info from my point:
The solution was to use the newest version of buildapp as #coredump mentioned. I updated by going to the github page, downloading the zip and doing the following commands at the point where buildapp is stored.
$ make
$ cp buildapp /usr/bin
(This of course only works on linux.)
This is not an elegant solution but buildapp hasn't updated in 4 years, I think it's a safe enough bet. I also made a mistake with the command. The --entry part is wrong. It should have been: `--entry ltk-colorpicker::main`` where main is a function that takes one variable since that's required by the spec.
Main is just this: (main (i) (declare (ignore i)) (colorpicker))

Run python script using existing ipython kernel without console

I can run a python script from a bash shell like so:
>> python script.py
I can also start an iPython kernel and connect multiple iPython consoles to the same kernel like so:
>> ipython kernel
...
To connect another client to this kernel, use:
--existing kernel-8987.json
then, for as many consoles as I would like, I execute
>> jupyter console --existing kernel-8987.json
However, what I would like to do is start a kernel, but then run scripts without opening a console. I'd like to do something like this:
>> ipython --existing kernel-8987.json script.py
Is this possible to do this somehow?
Extending on the other answer and use the %run magic command1, it's possible to do this (which works for multiple-line scripts):
$ jupyter console --simple-prompt --existing kernel-8987.json <<< '%run script.py'
or (on Windows where <<< doesn't work)
> echo %run script.py | jupyter console --simple-prompt --existing kernel-8987.json
Unfortunately, this method still prints some redundant prompt (In[1]:) on the console.
Alternatively, using Python API: (create a script to execute this Python code) (on my machine, this method is much faster)
from jupyter_client.manager import KernelManager
manager=KernelManager(connection_file="full path to connection file.json")
manager.load_connection_file()
manager.client().execute("commands to execute")
The commands to execute might span multiple lines, or have the form %run file.py.
There's also silent=True, store_history=False as parameters to execute().
The full path to the connection file can be found as
Path(jupyter_core.paths.jupyter_runtime_dir()) / "kernel-8987.json", or
jupyter_client.connect.find_connection_file("kernel-8987.json") (find file with specific name), or
jupyter_client.connect.find_connection_file() (find the latest file)
See also jupyter-client documentation.
Disclaimer: Some of the code are taken from jupyter-vim plugin, and manager.load_connection_file and connect.find_connection_file appears to be undocumented.
1: As mentioned in the documentation, the file is executed in a new namespace unless you use -i.
It seems that jupyter has this functionality already built in.
$ jupyter run --existing kernel-8987.json script.py
I don't know if this was a feature addition since the OP, or if I was really stupid and didn't RTFM.
$ jupyter run --help
Run Jupyter kernel code.
Options
=======
...
--existing=<CUnicode>
Connect to an already running kernel
Default: ''
Equivalent to: [--JupyterConsoleApp.existing]
The other answers will run the code in the existing kernel, but still open a console in the process. The run subcommand does exactly what I requested: runs the code without opening an interactive console.
% jupyter console --version
6.2.0
I can exec one-liners from a file like this:
% jupyter console --simple-prompt --existing kernel-8987.json < script.py

Ksh Script automatically calling another script in /usr/bin

I am executing a ksh script named abs.ksh located at /app/fao.... which connects to a server,
But the server is receiving a script named "ksh" which is present in /usr/bin...
I am not calling any script called ksh in abs.ksh(sorry cannot paste the code).
Also this happens only when the script is run in debug mode.
In non debug mode it works fine.
Can anyone give me a hint of what might be happening here.
In a standard "classic" Unix environment there may be multiple shells. E.g. 'sh' the original Bourne shell, 'ksh' - the Korn shell, csh - the C shell, bash, tcsh etc. etc.. A user login will have the default shell set per login.
The #! at the start of an executable script is an instruction to interpret & run the subsequent text with the name of the program following the '#!'.
E.g. run this with perl
#!/bin/perl
<.. perl stuff ..>
So yes #!/usr/bin/ksh - will run the script with the command interpreter (shell) at that location.
Need more info. wrt how you run in debug mode. I.e. are you typing 'ksh -x ...' or 'sh -x' - if so where is that on your search path. E.g. 'whence ksh' - maybe you're running with a different shell in debug mode.
Also which os is this ?

Resources