Is it possible to run Smalltalk scripts from the command line?

With gst, it's straightforward. Put this into hi.st:

Transcript show: 'Hi!'

Then run gst hi.st and you're done.

To pass arguments from the command line, you do as follows:

Transcript show: 'Hi ' , Smalltalk arguments first , '!'

Then run gst hi.st -a World


Pharo has decent command line support and a simple zeroconf script to install it:

curl get.pharo.org | bash
./pharo Pharo.image --help
./pharo Pharo.image eval "1+2"

We use these tools on a regular basis on our ci servers.

New command line handles can be installed easily by subclassing. You will find a partial documentation here.

Coral aims at more complex interfaces and supports complex parameter parsing. The default command line tools shipped with Pharo follow a rather simplistic approach and you have to check and process parameters manually.


Running a script from the command line is trivial with pretty much any Squeak version, certainly 5.3 or newer.

Basically {path/to/myVM} {path/to/myscript}

That myscript argument can be a URL pointing to a smalltalk code file or simply a filename. Since Smalltalk can read both code to install and code to run directly from a file, you can add some new code - consider it 'script functions' if you like - and then run whatever you want. So, at least on a unix machine, you can make a shell script that runs your VM and appends the filename of your intended script, and thus do sometihng like myshellscript mystuff.st

As an example, consider a script to work out and print the first Fibonacci number that requires one million digits.

#!/usr/bin/squeak /home/pi/Squeak/Squeak5.3-18560.image

!Integer methodsFor: 'mathematical functions' stamp: 'tpr 5/6/2019 12:22'!
fibonacci
"derived from https://www.nayuki.io/page/fast-fibonacci-algorithms"
"(1 to: 20) collect:[:i| i fastDoublingFib]"
"testing a quite large one - "
"8577 fibonacci= 13724780954457889052017147206983806244049002655849289934662148526555403650297300643609932653364630032094175733360509578504423049114004867523161091564824674600978308740378989479162611031273424686573759784740689516901416473328655422390895971263265867635819510949686102571388751758998017349379498918930220900180038324615253426530740473855269056304380498630108126734047701362218655030270360608989081398866489746698916626888016696892691933237089180504631788915650757757515944644732966345269202761471025651071790297611079540881155092137592980230998234868586211881093892491570520577408961869977892273540956424095750855208529072246641778982103984467921868950012668004047986803017482248992968482737462668300684879633714025755790485860328854796518843956263863014632532331145699658530054942590047273403691531821918862996422405159427262092477196755988981309029424760342802374213122162727840557722145891090413688461745240415668189577836068480363407847582529735341950500636735281963089675493707159434777756081146452522323681782226760627277553296721358921412115264845467834979154061137421532609247762981818564578019888974692581079593575783553856910367568474613323528337733872069223030834774749130478360574004172522316484339530942110067893000847800932306298725285623628731149337468217751734165148732164148285915275115006479682658150442259002271790547596033006363411193653337536041106069912826015502035140618407668385378737477702597473151509972754111640855347958033314453349633268543893894677097708945041254623018915871109789412793709229204261914803477697183287924195770678873001065036313926288444791424871512110658175954743584548831946767673488152740675550518235698898217693311515366329280005757014637854214769152690638778904780724293185353992279724740604674926819294787586671833537117545443846365508358918882"
    | a b c |
    a :=  0.
    b := 1.
    self highBit to: 1 by: -1 do:[:i||d e|
        d := ((b bitShift: 1) - a) * a.
        e := a squared + b squared.
        a := d.
        b := e.
        (self bitAt: i) = 1  ifTrue:[
            c := a + b.
            a := b.
            b := c]
        ].
    ^a! !


| t f|
t:= [f := 4784969 fibonacci] timeToRun.
FileStream stdout
    nextPutAll: 'fib(4784969) = '; 
    "nextPutAll: f asString; "
    cr; 
    nextPutAll: 'time = '; 
    nextPutAll: t asString; 
    nextPutAll: ' mS'; 
    cr.
Smalltalk snapshot: false andQuit: true

If you save this and set it to be executable the first line would run the script (this is from a Raspberry Pi and /usr/bin/squeak is a standard part of the distro) with the name of the script as the argument. It loads a bit of code to implement an interestingly clever algorithm, runs the test, outputs to stdout, and finally quits. It takes about 3 seconds on a Pi 4. Simply running the .st file will now work - ./myscript

It is, apparently, also possible to do clever tricks and register a magic pattern with the binfmt_misc facility so one could make st files have their own equivalent of the #! token.