Search code examples
node.jslinuxwindowselectronchild-process

How to run linux terminal commands on windows?


I'm not sure how to ask, but I'd like run the 'bash' command on windows 10 so that some linux commands run later. I'm using the framework Electron and the Child Process.

var os = require('os')
var exec = require('child_process').exec
if (os.platform() =='win32'){
    var cmd_win = 'bash'
    exec(cmd_win, function(error, stdout, stderr){
        console.log(error)
    });
}

The code snippet gives "Error: Command failed: bash". Does anyone know why? And can you help me? I hope you understood my question.


Solution

  • To initialize the WSL subsystem, you must launch a (hidden) Bash console window in the background, which doesn't work if you execute bash.exe directly - it works with neither exec nor execFile.

    The trick is to get the shell (cmd) process that Node.js spawns to launch bash.exe without blocking, which, unfortunately, isn't easy to do: start cannot be used, because bash.exe is a console application and therefore makes start act synchronously.

    The solution is to create an aux. VBScript file that launches bash.exe, which itself can be invoked asynchronously via wscript.exe. Note that the Bash console window is launched hidden:

    var os = require('os')
    var exec = require('child_process').exec
    if (os.platform() === 'win32') {
      var cmd_win = '\
        echo  WScript.CreateObject("Shell.Application").\
          ShellExecute "bash", "", "", "open", 0 > %temp%\launchBashHidden.vbs \
        & wscript %temp%\launchBashHidden.vbs'
      exec(cmd_win, function(error, stdout, stderr){
          if (error) console.error(error)
      });
    }
    

    Note that the aux. VBScript file %temp%\launchBashHidden.vbs lingers between invocations. Cleaning it up after every run would require more work (you can't just delete it right away, because wscript, due to running asynchronously, may not have loaded it yet).