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

David T. Lewis lewis at mail.msen.com
Wed Jul 6 22:30:00 UTC 2022

Hi Chris,

On Tue, Jul 05, 2022 at 06:19:29PM -0500, Chris Muller wrote:
> Hi Dave,
> In my bash shell, it correctly produces a list of 3 MAC addresses (one
> for each network interface).
>     ssh myserver cat "/sys/class/net/*/address"
> The quotes are needed by the bash shell because of the way it expands
> the *.  Okay, no problem so far.
> When I try to run the exact command above through OSProcess outputOf:,
> I get an empty String.
>     OSProcess outputOf: 'ssh myserver "cat /sys/class/net/*/address"'
>            "^^^ answers empty String"
> If I remove the quotes, I get only the LAST MAC address of the output
> as in bash (instead of all 3):
>     OSProcess outputOf: 'ssh myserver cat /sys/class/net/*/address'
>               "^^^ answers '00:00:00:00:00:00
> '  "
> And, finally, if I target the same command to my local laptop (without
> ssh prefix), then it works, I get the exact same output as from bash.
>       OSProcess outputOf: 'cat /sys/class/net/*/address'
>            "^^^ '00:00:00:00:00:00
> 43:27:69:a1:d9:36
> '
> The issue appears to be related to wildcard expansion when ssh is used
> to execute remotely..
> Any advice would be greatly appreciated.

I'll try to follow up with a fix if I can, but the basic issue you are
looking at here relates to command line expansion in unix shells.

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. 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'

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.

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.


More information about the Squeak-dev mailing list