3

The following function allows me to remotely execute Wolfram code on another machine that has wolframscript installed:

Attributes[remoteExecute] = {HoldAllComplete};
remoteExecute[(* remote_, *) expr_] := 
 Module[{compressed, ubuntuBox = RemoteConnect["192.162.0.2", "username", "password"]}, 
  compressed = ExportString[ToString[Hold[expr], InputForm], "Base64"];
  ToExpression[
   RemoteRunProcess[ubuntuBox, 
    "wolframscript -format InputForm -code 'ReleaseHold[ImportString[\
\"" <> compressed <> "\",\"Base64\"]]'", "StandardOutput"]]]

For example:

(* Return True: *)
FileExistsQ["~/only_on_my_remote_machine"] // remoteExecute

Problem: This function doesn't work on every function, however, and it is mysterious why:

How to fix?

George
  • 3,145
  • 7
  • 21
  • What's returned by the function? If it's a String that means the encoding didn't quite go right. By the way this would be easier to write as Compress[Unevaluated[expr] and then you would execute by calling Uncompress[compressed]. I think you might be happier with that. – b3m2a1 Aug 23 '19 at 15:49
  • b3m2a1: Is your proposed function then this one? – George Aug 23 '19 at 17:41
  • No. Don't use ExportString and don't use ImportString or ReleaseHold. Just do something like RemoteRunProcess[ubuntuBox, TemplateApply["wolframscript -format InputForm -code 'Uncompress[\"`\`\"]'", Compress[Unevaluated[expr]]] – b3m2a1 Aug 23 '19 at 17:43
  • I'm getting compression error output like Uncompress::corrupt: Compressed data "ïÂÂ" is corrupt and does
    not represent an expression.`
    – George Aug 23 '19 at 17:49
  • then something is likely going wrong in how you're sending it I figure. – b3m2a1 Aug 23 '19 at 17:50
  • b3m2a: Here is the way I'm sending it. – George Aug 23 '19 at 17:57
  • why did you put backslashes after the "\`"? Two backticks indicate a template in TemplateApply. – b3m2a1 Aug 23 '19 at 17:58
  • 1
    b3m2a1: Removing the backslashes worked! Thanks for your help. I think you accidentally included backslashes in your formatted markdown above^. – George Aug 23 '19 at 18:09
  • Ah right you are. Post a self-answer so people know this has been fixed. – b3m2a1 Aug 23 '19 at 18:09
  • b3m2a1: There is still an issue where this function doesn't allow me to (i) define custom local functions and then (ii) evaluate those local functions on the remote machine. See here to see what I mean. Is there any way around this? – George Aug 23 '19 at 18:36
  • That's a more subtle issue and deserves its own question – b3m2a1 Aug 23 '19 at 18:38
  • b3m2a1: See here for a new topic on the issue I raised. – George Aug 23 '19 at 18:52

1 Answers1

1

The following

Attributes[remoteExecute] = {HoldAllComplete};
remoteExecute[expr_] := 
 Module[{compressed, 
   ubuntuBox = RemoteConnect[ip, "username", "password"]}, 
  compressed = Compress[Unevaluated[expr]]; 
  ToExpression[
   RemoteRunProcess[ubuntuBox, 
    TemplateApply[
     "wolframscript -format InputForm -code 'Uncompress[\"``\"]'", 
     compressed], "StandardOutput"]]]

is able to execute functions remotely, so long as your function isn't locally defined.

George
  • 3,145
  • 7
  • 21