Search code examples
macosemacsparallels

Problems with prlctl exec inside emacs shell-mode window


Q: can anyone tell me how to run "prlctl exec" in an emacs shell-mode buffer?

---+ prlctl problems in emacs shell mode

I have a Windows virtual machine running on top of Parallels on a Mac.

I want to write some shell and Perl scripts that run on the Mac's OS-X UNIX-like environment, which invoke a Windows app on Parallels. Specifically FrameMaker.

Specifically, I want to be able to work in emacs, running native on the Mac, and then do esc-x compile to run a Makefile - said Makefile doing things like running FrameMaker ExtendScript commands, to do things like update the table of contents of a book in FrameMaker, save the FrameMaker files as text or PDF, etc. Basically, the usual sorts of automation that are unfortunately no longer so common.

I had this all working using Cygwin on Windows last year, but I switched to using a Mac with Parallels.

The prlctl command seems to be what I need to run a command. Specifically, "prlctl exec", or possibly "prlctl enter" for console type usage.

PROBLEM: prlctl exec does not run well in a shell-mode buffer under emacs on the Mac.

prlctl exec seems to run okay in a MacOS terminal window.

But in an emacs shell-mode buffer, well:

a) Running "prlctl enter" works an an emacs shell-mode buffer works. I can run DOS command-line type commands. But when I exit the "prlctl enter" session, it always exits the shell controlling the shell mode buffer.

b) Similarly, commands like "prlctl exec ..." run in an emacs shell-mode buffer, but when the exec'ed command terminates, it terminates the shell controlling the shell-mode buffer.

c) If I try to put the prlctl exec in the background, e.g. (prlctl exec ... &), things go crazy. What looks like keyboard control codes get sent to the shell controlling the emacs shell-mode buffer.

I conjecture that "prlctl" is remote controlling the Windows commands via some sort of pseudoterminal interception. And that it has been tested with an interactive MacOS terminal window, but it does not work with the pseudoterminals used for emacs shell-mode.

Q: has anyone managed to make something like thus work?

Saying "Just run the prlctl exec command from a Mac terminal window might almost be the right thing to do, although as an emacs native, it would be painful. But even when running from a Mac terminal window, I get problems with prtlctl that may be similar.

So far I have not been able to start FrameMaker up at all via prlctl, although I can easily start it up via a .BAT file or via PowerShell.

---+ Example of prlctl problem with emacs shell buffers

---++ prlctl enter running successfully in a mac terminal window

   Andy-Glew-MacBook-Pro:~ glew$ prlctl list
    UUID                                    STATUS       IP_ADDR         NAME
    {3b5c5ff5-2909-4a8b-a9e6-a54d909ba98c}  running      -               WinVM
    Andy-Glew-MacBook-Pro:~ glew$ prlctl enter WinVM
    Microsoft Windows [Version 6.3.9600]
    (c) 2013 Microsoft Corporation. All rights reserved.

    C:\>echo hi
    echo hi
    hi

    C:\>exit
    exit
    Andy-Glew-MacBook-Pro:~ glew$ 
    Andy-Glew-MacBook-Pro:~ glew$ 

---++ prlctl enter running in an emacs shell-mode buffer

$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c47  h1222 j0 $
$ bash  ~/hack $>
$ bash 1222 $>  prlctl enter WinVM
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\>echo hi
echo hi
hi

C:\>exit
exit
✓ 02:27:14 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c48  h1223 j0 $
$ bash  ~/hack $>
$ bash 1223 $>  exit

Process shell finished

The "exit" I typed in above caused the prlctl enter to exit, as it should - but it apparently also got sent to the emacs shell-mode controlling process.

---++ prlctl exec in a macos terminal window

Andy-Glew-MacBook-Pro:~ glew$ prlctl exec WinVM ipconfig | grep localdomain
   Connection-specific DNS Suffix  . : localdomain
Tunnel adapter isatap.localdomain:
   Connection-specific DNS Suffix  . : localdomain
Andy-Glew-MacBook-Pro:~ glew$ 

This works, I can type in more commands. And I can execute multiple prlctl execs in a script

---++ prlctl exec in an emacs shell-mode buffer

$ bash 1226 $>  prlctl exec WinVM ipconfig | grep local
   Connection-specific DNS Suffix  . : localdomain
   Link-local IPv6 Address . . . . . : fe80::958c:20a3:da02:2903%3
Tunnel adapter isatap.localdomain:
   Connection-specific DNS Suffix  . : localdomain
   Link-local IPv6 Address . . . . . : fe80::249d:2248:f52c:c8fc%5
✓ 02:31:43 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c45  h1227 j0 $
$ bash  ~/hack $>
$ bash 1227 $>  exit

Process shell finished

Again, it looks like an "exit" command is being supplied to the Windows command interpreter by prlctl exec - it looks like prlctl exec is built on top of prlctl enter - and is being supplied to both the Windows command interpreter and to the emacs shell-mode controlling process.

---++ Backgrounding a prlctl exec command in a Mac terminal window

First, unbackgrounded:

Andy-Glew-MacBook-Pro:~ glew$ prlctl exec WinVM ipconfig | grep localdomain 
   Connection-specific DNS Suffix  . : localdomain
Tunnel adapter isatap.localdomain:
   Connection-specific DNS Suffix  . : localdomain

Then, backgrounded:

Andy-Glew-MacBook-Pro:~ glew$ prlctl exec WinVM ipconfig | grep localdomain &
[1] 63866
Andy-Glew-MacBook-Pro:~ glew$ 

[1]+  Stopped                 prlctl exec WinVM ipconfig | grep localdomain

It hangs hre for a while. It appears that, even in a MacOS terminal window, some sort of contrlling tty access is required by prlctl exec - even though it should not be for this command.

Andy-Glew-MacBook-Pro:~ glew$ fg
prlctl exec WinVM ipconfig | grep localdomain

^C^C
^D
^ZAndy-Glew-MacBook-Pro:~ glew$ 
Andy-Glew-MacBook-Pro:~ glew$ 
Andy-Glew-MacBook-Pro:~ glew$ 

---++ Backgrounding a prlctl exec command in an emacs shell-mode buffer

The session text is indented.

I will annotate

First, the shortest prlctl exec command I know:

$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c44  h1226 j0 $
$ bash  ~/hack $>
$ bash 1226 $>  prlctl exec WinVM echo hi &
[1] 63659
✓ 02:39:20 PM Saturday 2015-10-17

It paused here for a while, but eventually the stiff below appeared - it looks like prlctl is sending an "exit" back to the shell mode.

$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c45  h1227 j1 $
$ bash  ~/hack $>
$ bash 1227 $>  exit

Process shell finished

With a longer command, like "prlctl exec ... ipconfig", more stuff appears:

$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c44  h1227 j0 $
$ bash  ~/hack $>
$ bash 1227 $>  prlctl exec WinVM ipconfig | grep localdomain &
[1] 58231
✓ 02:36:10 PM Saturday 2015-10-17

Above is the prlctl exec command I entered.

$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c45  h1228 j1 $
$ bash  ~/hack $>
$ bash 1228 $>  exit
There are stopped jobs.

[1]+  Stopped                 prlctl exec WinVM ipconfig | grep localdomain
✓ 02:36:10 PM Saturday 2015-10-17

OK, it paused here for a while. And then it looks like prlctl exec starts sending crap to the emacs shell-mode controlling process:

$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c45  h1229 j1 $
$ bash  ~/hack $>
$ bash 1229 $>  [2] 58298
✓ 02:36:10 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c46  h1230 j2 $
$ bash  ~/hack $>
$ bash 1230 $>  bash: his:: command not found
✗ 02:36:10 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c47  h1231 j2 $
$ bash  ~/hack $>
$ bash 1231 $>  bash: s: command not found
✗ 02:36:10 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c48  h1232 j2 $
$ bash  ~/hack $>
$ bash 1232 $>  ✗ 02:36:10 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c48  h1233 j2 $
$ bash  ~/hack $>
$ bash 1233 $>  bash: e: command not found

It is like they are sending text to the shell that is not getting echoed (probably a result f emacs configuration), and causing various hiccups:

[2]+  Stopped                 prlctl exec WinVM ipconfig | grep localdomain
✗ 02:36:10 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c49  h1234 j2 $
$ bash  ~/hack $>
$ bash 1234 $>  bash: syntax error near unexpected token `.*'
✗ 02:36:10 PM Saturday 2015-10-17
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c49  h1235 j2 $
$ bash  ~/hack $>
$ bash 1235 $>  > > > ✗ 02:36:10 PM Saturday 2015-10-17
bash: syntax error near unexpected token `1'
  > > > ✗ 02:36:10 PM Saturday 2015-10-17
bash: syntax error near unexpected token `1'

Now I get a lot of this stuff... snipping ...

bash: syntax error near unexpected token `1'
✗ 02:36:10 PM Saturday 2015-10-17
> > > > > > > > > > > > > > > > > > bash: syntax error near unexpected token `)'
✗ 02:36:10 PM Saturday 2015-10-17
bash: !s\21\^KE\332n\216^C\340^C\262^E\223\377\315^D^W\236^D\375\236\270^D\325^P^[^?\376^C\234g000O\205UE\257p: event not found
✗ 02:36:10 PM Saturday 2015-10-17
[3] 58511
[3]   Exit 127                Q\320^C\3660\307\203\351wk\244
✗ 02:36:10 PM Saturday 2015-10-17

... lots more of the same - looks like control codes

✗ 02:36:10 PM Saturday 2015-10-17
bash: syntax error near unexpected token `)'
✗ 02:36:10 PM Saturday 2015-10-17
bash: syntax error near unexpected token `&'

Process shell bus error: 10

Actually, I almost hesitate to show the previous line, since it suggests a shell bug.

---+ Config Info

MacBook Pro mid 2014

$ bash 1229 $>  uname -a
Darwin Andy-Glew-MacBook-Pro.local 14.5.0 Darwin Kernel Version 14.5.0: Wed Jul 29 02:26:53 PDT 2015; root:xnu-2782.40.9~1/RELEASE_X86_64 x86_64

Parallels version

$ bash 1230 $>  prlctl --version
prlctl version 10.3.0 (29227) rev 0


From the Parallels Desktop about:
Version 10.3.0 (29227)
(same as for the command line)

Windows Version

Manually editing systeminfo to keep only the good bits

$ bash 1232 $>  prlctl exec WinVM systeminfo

OS Name:                   Microsoft Windows 8.1 Pro
OS Version:                6.3.9600 N/A Build 9600
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Standalone Workstation
OS Build Type:             Multiprocessor Free

System Boot Time:          10/17/15, 1:56:38 PM
System Manufacturer:       Parallels Software International Inc.
System Model:              Parallels Virtual Platform
System Type:               x64-based PC
Processor(s):              1 Processor(s) Installed.
               [01]: Intel64 Family 6 Model 70 Stepping 1 GenuineIntel ~2793 Mhz
BIOS Version:              Parallels Software International Inc. 10.3.0 (29227) rev 0, 9/21/15

Total Physical Memory:     12,272 MB
Available Physical Memory: 8,753 MB
Virtual Memory: Max Size:  14,128 MB
Virtual Memory: Available: 10,808 MB
Virtual Memory: In Use:    3,320 MB
$ bash glew@Andy-Glew-MacBook-Pro [~/hack]  c47  h1233 j0 $
$ bash  ~/hack $>
$ bash 1233 $>  exit

Process shell finished

and, as usual, prlctl exec closes the emacs shell-mode buffer I ran in in

(emacs-version)

GNU Emacs 24.4.1 (x86_64-apple-darwin14.0.0, NS apple-appkit-1343.16) of 2015-01-17 on Andys-MacBook-Pro.local

Solution

  • In order to run a Parallels exec in background, I've found 2 different ways of doing that:

    Sending null to STDIN and your command should provide no output. See the example:

    prlctl exec 'Windows XP' /temp/script.bat argument1>NUL </dev/null &
    

    Executing each prlctl command in a different shell using xargs, where you can define maximum number of simultaneous process:

    echo var1 var2 var3 | xargs -I{} -P 4 bash -c "prlctl exec 'Windows XP' /temp/script.bat argument1>NUL"
    

    See this working example (works on Linux and Mac):

    seq 10 | xargs -I{} -P 4 bash -c "echo start {}; sleep 3; echo done {}"
    

    I hope this helps