[squeak-dev] How to use OSProcess with stdin and stdout

Martin Kuball martinkuball at web.de
Fri May 22 20:35:08 UTC 2020


Hi David,

I finally found a solution to my problem. Successfully converted 1300 images in
a couple of minutes. The code I come up with is roughly the following (using
the wc program here as a proof of concept before switching to tesseract and
image data for the input):

| input output stdErr proc accessProtect res err |
input := ExternalPipe nonBlockingPipe.
output := ExternalPipe blockingPipe.
stdErr := ExternalPipe nonBlockingPipe.
proc := ExternalOSProcess concreteClass
	programName: '/usr/bin/wc'
	arguments: #('-w')
	initialEnvironment: nil.
proc initialStdIn: input reader.
proc initialStdOut: output writer.
proc initialStdErr: stdErr writer.
accessProtect := Semaphore forMutualExclusion.
accessProtect critical: [
	proc value.
	input nextPutAll: 'this is a test'.
	input closeWriter.
	res := output upToEndOfFile.
	err := stdErr upToEndOfFile
].
proc waitForTermination.
output close.
stdErr close.
proc exitStatus ~= 0
	ifTrue: [^ 'error ' , proc exitStatus , ': ' , err].
	ifFalse: [^res]


Mybe it is possible to reuse more of your high-level code. But I wanted low
overhead and complete control over the input and output streams.

By the way uninstalling an older version of OSProcess and installing the new
one left a OSProcess watcher with an ObsoleteUnixOSProcessAccessor running.

And a final question: If you want to get a deeper understanding of process
handling in squeak, what would you recomend to read? Is the blue book still a
good reference?

Thanks again for your help and the great code.

Martin



Am Samstag, 16. Mai 2020, 00:13:19 CEST schrieb David T. Lewis:
> Hi Martin,
>
> On Fri, May 15, 2020 at 09:20:17PM +0200, Martin Kuball wrote:
> > Am Donnerstag, 14. Mai 2020, 23:27:59 CEST schrieb David T. Lewis:
> > > On Thu, May 14, 2020 at 09:37:26PM +0200, Martin Kuball wrote:
> > > > Hi!
> > > >
> > > > I'm trying to do some OCR from squeak using tesseract. I installed
> > > > OSProcess. So far so good. But I don't know what classes to use for
> > > > stdIn
> > > > and stdOut. My>
> > > >
> > > > code would look something like this:
> > > > | proc stdIn stdOut d |
> > > >
> > > > stdIn := ???
> > > > stdOut := ???
> > > > proc := ExternalUnixOSProcess forkAndExec: '/usr/bin/tesseract'
> > > > arguments:
> > > > #('-' '-' '--dpi' '100') environment: nil descriptors: (Array with:
> > > > stdIn
> > > > with: stdOut with: nil).
> > > > proc ifNil: [self class noAccessorAvailable].
> > > > d := Delay forMilliseconds: 50.
> > > > [proc runState == #complete] whileFalse: [d wait].
> > > > " and now read the text from stdOut..."
> > > >
>  > > > Can someone fill in the blanks or point me to code that does similar
> > > >
> > > > things? Thanks very much.
> > >
> > > Hi Martin,
> > >
> > > First, please also install CommandShell in addition to OSProcess. Get
> > > the
> > > latest versions of both OSProcess and CommandShell, regardless of the
> > > version of Squeak you are using. If you are using SqueakMap to load
> > > them,
> > > then please select the versions labelled "(head)".
> > >
> > > Start out by trying something like this:
> > >     OSProcess outputOf: 'tesseract - - --dpi 100'
> > >
> > > I'm not sure if this will do what you want but please give it a try,
> > > and if it does not work I'll try to give a better answer.
> > >
> > > This uses a couple of new methods that I added to OSPrecess recently,
> > > but have not mentioned until now. If it proves to be useful you, you
> > > will be the first :-)
> > >
> > > Assuming that it works, here is what will have happened:
> > >
> > > - The argument string is parsed into a unix-style command pipeline
> > >
> > > - The pipeline is all objects, with OS process proxies doing the work
> > >
> > > - When evaluated, and stderr result will show up in an error notifier
> > >
> > >   in your image (proceed though the notifier)
> > >
> > > - Command stdout is collected and answered as the result of #outputOf:
> > >
> > > I would recommend running this in a debugger so you can step through
> > > it and see what is going on.
> > >
> > > Dave
> >
> > Hi Dave,
> >
> > thanks for your answer. Acutally I did install CommandShell because I
> > thougth it might help me understand the usage of OSProcess. And maybe it
> > will if I give it more time.
> >
> > So here is what I did: I configure the following repository:
> >
> > MCHttpRepository
> >
> > 	location: 'http://www.squeaksource.com/OSProcess'
> > 	user: ''
> > 	password: ''
> >
> > and installed OSProcess-Base dtl.71, OSProcess-AIO dlt.9 and
> > OSProcess-Unix
> > dtl.35. But I do not see any mention of a head label. So where did I go
> > wrong?
> From the OSProcess repository, load OSProcess-dtl.118. From the CommandShell
> repository, load CommandShell-dtl.109. These are currently the most recent
> versions. Ignore the sub-packages such as "OSProcess-Unix", that is
> something I did to support Pharo (something of a fools errand if I may say
> so). All of the sub-packages are included in the full OSProcess and
> CommandShell packages.
>
> A shortcut to do this is:
>
> 	Installer ss project: 'OSProcess'; install: 'OSProcess'.
> 	Installer ss project: 'CommandShell'; install: 'CommandShell'.
>
> The "(head)" version labels in the SqueakMap package loader do the same
> thing, except for the alarming warning messages which you can safely ignore.
> > The command you suggested worked. At least if I provide the image to
> > tesseract as a file. I will go on with the debugger and try to find out
> > how to feed the image data to stdIn.
>
> The basic Unix shell redirector operators #> and #< should work. For
> example, try evaluating this:
>
>    OSProcess outputOf: 'cat < /etc/services | edit'
>
> I am not familiar with tesseract, but you can probably use the same
> approach.
>
> Dave






More information about the Squeak-dev mailing list