Upsh stands for Unix to Prolog shell. It is a Prolog program which can be used to run Prolog programs from the command line or as scripts. It originally ran on three Prolog engines without changes to the source code. Current versions are only tested on SWI-Prolog.
With version 3, Upsh has all the features I had envisaged and many which I just thought of on the way. It is also fairly stable and actively maintained. The development has now been switched to SWI and upsh is also provided as an easy to install SWI pack.
The pack has a single main predicate which creates an executable state that provides a convenient way of executing prolog scripts from the command line (cli = command line interaction/invocation). The state can be invoked by calling the created executable (upsh) on command line. By default the upsh binary is placed in same directory as the swipl executable. Only tested on Linux.
Install: ?- pack_install(upsh).
This should also create the executable (upsh). The executable can be also be created explicitly with:
?- use_module(library(upsh)). ?- upsh_make. ?- halt.
Ask your shell to re-read its executables with something like rehash, and the upsh executable should be on your path.
> rehash > upsh say naku % /home/nicos/.rcpl compiled 0.00 sec, 8 clauses % /home/nicos/bin/cline_upsh/say.pl compiled 0.00 sec, 5 clauses naku > upsh v upsh_exec(upsh(3:0:0),swi(10:1:4),built_on(2026/3/9,18:55:45))
The executable will look for scripts via the following mechanisms.
A command line invocation like
> cd $HOME > upsh say naku % /home/nicos/.local/share/swi-prolog/pack/upsh/scripts/say.pl compiled 0.00 sec, 6 clauses naku
names the script say so upsh will look for a prolog file say.pl.
To locate this, upsh will first look in current directory, then in $HOME/bin/cline_upsh/
and finally in PACK/scripts directory of all installed packs. The last of those is
how in the above example upsh can locate script say.pl in installed pack
$HOME/.local/share/swi-prolog/pack/upsh/scripts/say.pl.
When no script name is given upsh will try to infer one.
Select the single .pl file in current directory.
If multiple .pl files exist in current directory select the one that shares its basename with the directory name.
As of v3 users can define a predicate for auto locating scripts in user_profile(upsh_script_sel.pl)
defining upsh_script_sel/1 which should return the name of the script.
The idea is that the predicate will look into the current directory and recognise the type of operation that is required.
For instance, in directories with a single .tex file named submit.tex in them, my locator predicate will select the script that runs pdflatex and a pdf viewer on the produced output.
So, in this scenario the user can simply call
> ls submit.bib submit.tex .... > upsh
Once the input program/script has be loaded, upsh will call the entry predicate possibly
passing any OS arguments that are meant for the script as input.
For a program such as, _|say.pl, the default behaviour is to look for defined predicate say/0, say/1, say/n,
main/0, main/1, and main/n. It will then call the first of those that is defined and matches
any passing arguments. In the case of arity one predicates, if there are multiple
arguments to be passed, then they will be passed as a single list.
Upsh by default converts OS arguments to Prolog terms:
> upsh say a=b % /home/nicos/bin/cline_upsh/say.pl compiled 0.00 sec, 5 clauses a(b) > upsh say a=b,c do=end a(b,c) do(end) > upsh say a=lst=b,c atm=alpha=beta a([b,c]) 'alpha=beta'
\\ escapes elements of construction of terms
> upsh say abc\\=abc a=b\\,c abc=abc a((b,c))
To pass term functor =, you can also use ==
> upsh say alpha==beta alpha=beta
To terminate nested arguments use ":"
άμÏελοÏ;upsh/scripts> upsh say a=t=x=y,7 a=t=x=y:7 a=t=x=y::7 % /home/nicos/pl/packs/src/upsh/scripts/say.pl compiled 0.00 sec, 6 clauses a(t(x(y,7))) a(t(x(y),7)) a(t(x(y)),7)
Variables can be passed to the script and identified.
> upsh say p a alpha=beta,X gamma=delta=atm=Y
alpha(beta,_1088)
gamma(delta('Y'))
upsh_vs(['X'=_1088])
To avoid translation of Program arguments
> upsh say p o - alpha=beta 'alpha=beta'
To edit the Program source file
> upsh l=e say.pl or > upsh say.pl l=e
The executable takes a number of one letter flags:
| h | print help message (and exit) |
| v | show versions info (and exit) |
| b | verbose, show info on translation of args |
| p | suppresses loading messages |
| f | skip loading initialisation files |
| e/1 | direct error messages to file |
| d/1 | declares working directory |
| l/1 | select loading method |
| b pass to lib/1 | |
| d load (do not call entry) | |
| e edit the target script | |
| l print location of script and exit | |
| m compile | |
| n consult | |
| n/1,2 | name (and arity) of entry predicate |
| o | do not translate Program arguments |
| _-_ | treat remaining inputs as Program args |
| a | pass all input variables into last arg |
| Old functionality | |
| c | command line invocation |
| s | script invocation |
| i/2 | provider script |
| t/1 | script Program |
| y/2 | pred to spy-not working due to SWI changes |
If you use Upsh for a while I would appreciate an email with the kind of scripts you using it with, at http://stoics.org.uk/~nicos/sware/contact.html
Opts
current_prolog_flag( home, Home ).The following predicates are exported, but not or incorrectly documented.