WSL run linux from windows without spawning a cmd-window

为君一笑 提交于 2019-12-08 23:11:05

问题


I have WSL bash running in a cmd. I don't use it for anything, it just hangs there to keep the WSL system alive.

When I start X applications:

bash -c "DISPLAY=:0 xmessage hello &"

I get this result:

I can close down the command window without any problems, but it's rather annoying.

How can run commands without getting this cmd window every time?


回答1:


Here's a simpler solution that requires a WSH-based helper script, however:

wscript .\runHidden.vbs bash -c "DISPLAY=:0 xmessage 'hello, world'"

To apply @davv's own launch-in-background technique to avoid creating a new bash instance every time:

One-time action (e.g., at boot time): launch a hidden, stay-open bash window. This spawns 2 bash processes: the Windows bash.exe process that owns the console window, and the WSL bash process (owned by the WSL init singleton), which is then available for servicing background commands.

wscript .\runHidden.vbs bash # hidden helper instance for servicing background commands

For every X Window-launching command: Terminate each command with & to have it be run by the hidden WSL bash instance asynchronously, without keeping the invoking bash instance alive:

wscript .\runHidden.vbs bash -c "DISPLAY=:0 xmessage 'hello, world' &"

runHidden.vbs source code:

' Simple command-line help.
select case WScript.Arguments(0)
case "-?", "/?", "-h", "--help"
  WScript.echo "Usage: runHidden executable [...]" & vbNewLine & vbNewLine & "Runs the specified command hidden (without a visible window)."
  WScript.Quit(0)
end select

' Separate the arguments into the executable name
' and a single string containing all arguments.
exe = WScript.Arguments(0)
sep = ""
for i = 1 to WScript.Arguments.Count -1
  ' Enclose arguments in "..." to preserve their original partitioning.
  args = args & sep & """" & WScript.Arguments(i) & """"
  sep = " "
next

' Execute the command with its window *hidden* (0)
WScript.CreateObject("Shell.Application").ShellExecute exe, args, "", "open", 0

Even when launched from a GUI app (such as via the Run dialog invoked with Win+R), this will not show a console window.

If you've configured your system to execute .vbs scripts with wscript.exe by default (wscript //h:wscript /s), you can invoke runHidden.vbs directly, and if you put it in your %PATH%, by filename (root) only: runHidden ....

Note that use of the script is not limited to console applications: even GUI applications can be run hidden with it.




回答2:


There's another simple solution, it requires an external executable though. It has no dependencies and was recommended by aseering on GitHub.

you can launch bash via run.exe: run.exe bash.exe -c "<whatever Linux command>". (run.exe is available here: http://www.straightrunning.com/projectrun/ , make sure you download the 64-bit version, the 32-bit version will not be able to find or run bash).

With run on the search PATH, you can just call

run bash -c "DISPLAY=:0 xmessage hello"




回答3:


So I just made this workaround for now. I really hope that there's a better way than this, but here it goes:

In the command prompt that lives purely to keep WSL alive, I have this script running:

wsl_run_server

#!/bin/bash
set -e
nc -kl 127.0.0.1 15150 | sh

And then I have this command to execute commands in background:

wsl_run_background_command

if ! pidof -x bin/wsl_run_server; then
    echo wsl_run_server isnt running!
    exit 1
fi
echo \($@\) \& | nc localhost 15150

from windows I then call:

bash -c "DISPLAY=:0 ~/bin/wsl_run_command xmessage hello"


来源:https://stackoverflow.com/questions/41225711/wsl-run-linux-from-windows-without-spawning-a-cmd-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!