Administrator
|
I'm trying to pass a multiline argument, but none of the things that work in the shell seem to work with OSP.
I passed both of the following to PipeableOSProcess>>waitForCommand: with a "No such file or directory" error, which usually means that the multiline part was not processed correctly. However, if I copy/paste them into the shell, they work fine heredoc: '/usr/bin/osascript -ss <<-EOF tell application "Safari" to activate tell application "Terminal" to activate EOF' double-quoted string: '/usr/bin/osascript -ss -e " tell application \"Safari\" to activate tell application \"Terminal\" to activate"' Why are these not working? Thanks. Sean
Cheers,
Sean |
On Fri, Feb 24, 2012 at 1:53 PM, Sean P. DeNigris <[hidden email]> wrote: I'm trying to pass a multiline argument, but none of the things that work in OSP is not a shell. Ask yourself what a program receives when iyt is invoked with the two examples above. Then provide the equivalent argument to OSP and you'll find it'll work. OSP is an interface to exec. A shell is an interface to exec. OSP doesn't parse arguments, just passes them onto exec. A shell does parse arguments before passing them onto exec. So the shell input
" tell application \"Safari\" to activate tell application \"Terminal\" to activate" is a string argument which in Smalltalk would be written
(String with: Character lf), 'tell application "Safari" to activate', (String with: Character lf), 'tell application "Terminal" to activate'
HTH
best, Eliot |
Administrator
|
That's good to know. Thanks. I investigated further and accidentally found out that it wasn't the multi-line part at all that was the problem. It was that my string contained an ellipsis, which forced the argument to waitForCommand: into a WideString. Is there a workaround? can OSP only handle ByteStrings? Thanks. Sean
Cheers,
Sean |
In reply to this post by Eliot Miranda-2
On Fri, Feb 24, 2012 at 02:00:12PM -0800, Eliot Miranda wrote:
> On Fri, Feb 24, 2012 at 1:53 PM, Sean P. DeNigris <[hidden email]>wrote: > > > I'm trying to pass a multiline argument, but none of the things that work > > in > > the shell seem to work with OSP. > > > > I passed both of the following to PipeableOSProcess>>waitForCommand: with a > > "No such file or directory" error, which usually means that the multiline > > part was not processed correctly. However, if I copy/paste them into the > > shell, they work fine > > > > heredoc: > > '/usr/bin/osascript -ss <<-EOF > > tell application "Safari" to activate > > tell application "Terminal" to activate > > EOF' > > > > double-quoted string: > > '/usr/bin/osascript -ss -e " > > tell application \"Safari\" to activate > > tell application \"Terminal\" to activate"' > > > > Why are these not working? > > > > OSP is not a shell. Ask yourself what a program receives when iyt is > invoked with the two examples above. Then provide the equivalent argument > to OSP and you'll find it'll work. OSP is an interface to exec. A shell > is an interface to exec. OSP doesn't parse arguments, just passes them > onto exec. A shell does parse arguments before passing them onto exec. So > the shell input > > " > tell application \"Safari\" to activate > tell application \"Terminal\" to activate" > > is a string argument which in Smalltalk would be written > > (String with: Character lf), 'tell application "Safari" to > activate', (String with: Character lf), 'tell application "Terminal" to > activate' > Exactly so. PipeableOSProcess class>>command: will take the string you provide and pass it directly to a unix shell (/bin/sh which in most cases is a link to bash). It will exec that /bin/sh program, providing your input string directly to /bin/sh for processing. In turn, /bin/sh does its normal processing, and executes whatever programs you asked it to run. This means that the string you provide as input should contain exactly the characters that you would have typed on a keyboard and sent through the terminal driver to the /bin/sh program. Any <cr> or <lf> characters, quote marks, and so forth in the the string are passed directly to the /bin/sh program, which is the program that actually executes your command. This may seem confusing if you are trying to send multiple lines of text to the shell, because the "multiple lines" are really just a string with some <cr> or <lf> characters embedded. You think of them as lines of text because the unix terminal driver handling your keyboard processes them that way; it waits until you hit your "enter" key before passing a line of input to the shell. But from the point of view of the shell, it is just a stream of bytes being sent to the shell, and by convention the shell treats a bunch of characters ending with a <lf> as a line of input. Of course it is possible to handle a lot of this input parsing in Smalltalk, and that is what the classes in package CommandShell do. This allows you to do the input parsing directly without the assistance of a unix /bin/sh program. In other words, in your example we would separate the lines of input text, parse each line to interpret the tokens and expand file names as if we were a unix shell, and then directly invoke each individual program in each command line without the assistance of a real unix shell. And because each program that you run ends with an exit status code that it provides to the shell, we can make use of that exit status in Smalltalk, and do some conditional processing just as might be done by the real /bin/sh program. Dave |
In reply to this post by Sean P. DeNigris
On Fri, Feb 24, 2012 at 03:46:58PM -0800, Sean P. DeNigris wrote:
> > Eliot Miranda-2 wrote > > > > OSP is an interface to exec. > > That's good to know. Thanks. > > I investigated further and accidentally found out that it wasn't the > multi-line part at all that was the problem. It was that my string contained > an ellipsis, which forced the argument to waitForCommand: into a WideString. > Is there a workaround? can OSP only handle ByteStrings? OSProcess connects to external processes using a StandardFileStream rather than a MultiByteFileStream, and I suspect that this is related to your problem. Squeak's multi-byte character support did not yet exist when I wrote OSProcess and CommandShell, and I am afraid that an update for this is long overdue ... In any case, if you can think of a way to convert your multi-byte input string into exactly the steam of bytes that the program expects on its input (more or less as Eliot was suggesting in his reply), then you may find that it works. I don't have a Mac to try any of this on, so I really should not attempt to guess at it, but I have a hunch that if you were to convert your multi-byte input string into a byte array, thence back to a string of 8-bit characters (two "characters" for each 16-bit character), then feed this to a PipeableOSProcess, it might just work. Please let me know in the unlikely event that I guessed right ;-) Dave |
Administrator
|
I tried aWideString asByteArray asString (as well as some other experiments), which did not work. Is that what you meant? Thanks. Sean
Cheers,
Sean |
On 28.02.2012, at 03:58, Sean P. DeNigris wrote: > > David T. Lewis wrote >> >> I have a hunch that if you were >> to convert your multi-byte input string into a byte array, thence back >> to a string of 8-bit characters > > I tried aWideString asByteArray asString (as well as some other > experiments), which did not work. Is that what you meant? Err, no. You need to encode it. Try squeakToUtf8. This converts from a WideString to a ByteString using UTF8 encoding. - Bert - |
Free forum by Nabble | Edit this page |