[squeak-dev] wildcard expansion with OSProcess outputOf: through ssh

Chris Muller ma.chris.m at gmail.com
Thu Jul 7 01:57:35 UTC 2022


> If you started with this command line:
>     $ ssh dan.box.squeak.org cat /sys/class/net/*/address
> then your intent was probably to pass the '/sys/class/net/*/address' parameter
> over to the remote system through ssh, where the shell over there would
> expand the $* wild card on the remote system.


> But what is actually happening
> is that the expansion is happening on your local box, which just happens
> to have similar looking things in its /sys/class/net/ directory, then passing
> the expanded results over to the remote system through ssh.

Oh, my!!

> The resulting
> path strings probably do not match what is actually on that remote system,
> so you end up with file not found errors in the result (more on that below,
> there was a bug in OSProcess that masked the error).
> The way to handle this in a unix shell is to escape the $* wild card so
> that it will be passed over to the remote system to be expanded over there.
> On a unix shell you can excape the wildcard character like this:
>     $ ssh dan.box.squeak.org cat /sys/class/net/\*/address
> or by quoting the whole path string like this:
>    $ ssh dan.box.squeak.org cat '/sys/class/net/*/address'
... (from your 2nd reply)...
> Try evaluating this:
>       OSProcess outputOf: 'ssh dan.box.squeak.org ''cat /sys/class/net/*/address'' '.
> CommandShell will understand the single quote characters as escaping the
> string that they surround, similar to the behavior of bash. You have to
> escape the single quotes in your Smalltalk string, so they look like the
> above in the Smalltalk expression. This will let the path with wild card
> get passed as a single string parameter over to the remote system via ssh,
> where it will be properly expanded on the remote system.

This is immensely illuminating!  Not just the fix, but a better
understanding of how things work.  By literal quoting (with single
quotes) the entire remote command, it'll ensure to treat it as a
single literal argument to the local ssh command that, instead of, as
with my erroneous use of double quotes, processing it via my local
filesystem before even _beginning_ to execute the ssh command.  Now
that you've pointed it out, it seems obvious..  I think.   :/

Hmm, because I'm still fooled by the fact that double quotes works on
in my terminal -- passing it to the remote system like I want instead
of processing it via my local system first..  oh well.  This fix to
pass the command as a literal string is safe and makes sense.

> The next issue is that we are trying to invoke one of these command lines
> using CommandShell, which is yet another layer of shell command line
> interpretation.
> CommandShell is a very simple unix-like shell, but it does
> not include things that you would expect from a bash shell such as shell
> variables and proper escaping of wild cards. I do not have a suggestion
> to addess this at the moment but I'll try to follow up with something later.

Oh, that's good to know.  I just tried,

   OSProcess outputOf: 'echo $HOME'

and it returned '$HOME'.  Yikes!

Hmm.. this is an unexpected limitation.
I just tried to quickly research a way to pass a string of key=value's
syntax to the bash command itself, something like:

   OSProcess outputOf: 'bash --environment ''key1=value1'' -c ''ssh
dan ''cat /sys/class/net/*/address'''

where my code would replace "key1=value1", above, with every entry in
the 'environment' Dictionary of UnixProcess, which appears to contain
the environment for the squeak vm process.

--environment, above, is bogus, just for illustration, I don't know
quite how to do it.  I don't even know if this is a good approach at

You've already done a lot, and I'm grateful, but if you think of any
good solutions to accessing environment variables in #outputOf:
strings, please let me know!  :)

> Finally, your example exposed a bug in OSProcess class>>outputOf: which
> was in this case failing to report the error output of your ssh command
> due to a timing issue related to reading from the error output pipe. It's
> fixed now in OSProcess-dtl.128, so if you update you will probably see more
> meaningful error notifications with you run the ssh command.

An amazing and unexpected turnaround, Dave.  OSProcess is Squeak's
most important external package.

 - Chris

More information about the Squeak-dev mailing list