来自 windows 的 WSL 运行 linux 没有产生 cmd-window

WSL run linux from windows without spawning a cmd-window

我在 cmd 中安装了 WSL bash 运行ning。我什么都不用它,它只是挂在那里让 WSL 系统保持活动状态。

当我启动 X 应用程序时:

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

我得到这个结果:

我可以关闭命令 window 没有任何问题,但它很烦人。

如何运行命令而不每次都得到这个命令window?

所以我现在只是做了这个解决方法。我真的希望有比这更好的方法,但就是这样:

在纯粹为了让 WSL 保持活力而存在的命令提示符中,我有这个脚本 运行:

wsl_run_server

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

然后我有这个命令在后台执行命令:

wsl_run_command

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

来自 windows 然后我打电话给:

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

这是一个更简单的解决方案,但是,它需要一个基于WSH的帮助程序脚本runHidden.vbs(见底部):

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

应用@davv 自己的后台启动技术来避免每次都创建一个新的 bash 实例:

一次性操作(例如,在启动时):启动一个隐藏的、保持打开的bashwindow。这会生成 2 bash 进程:拥有控制台 Windows bash.exe 进程 window,以及 WSL bash 进程(由 WSL init 单例拥有),然后可用于服务 后台命令

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

For every X Window-launching command: 用&终止每个命令让它成为运行 由隐藏的 WSL bash 实例 异步 ,而不保持 调用 bash 实例活动:

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

runHidden.vbs源代码:

' 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, if necessary.
  if Instr(WScript.Arguments(i), " ") > 0 then
    args = args & sep & """" & WScript.Arguments(i) & """"
  else
    args = args & sep & WScript.Arguments(i)
  end if
  sep = " "
next

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

即使从 GUI 应用启动(例如通过 Win+R 调用的 Run 对话框),也不会显示控制台 window.

如果您的系统配置为默认执行 wscript.exe.vbs 脚本wscript //h:wscript /s,我认为这是默认配置),你可以直接调用 runHidden.vbs,如果你把它放在你的 %PATH% 中,仅通过文件名(root):runHidden ...

请注意,脚本的使用不限于 控制台 应用程序:甚至 GUI 应用程序也可以 运行 隐藏。

还有另一个简单的解决方案,不过它需要一个外部可执行文件。它没有依赖项,由 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).

在搜索 PATH 上使用 run,您只需调用

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

运行命令背景

screen -dmS [name] [command]

例子

screen -dmS gui bash -c "DISPLAY=:0 xmessage hello"

在 windows 桌面上创建快捷方式(运行 在 wsl 中)

wslusc screen -dmS gui bash -c "DISPLAY=:0 xmessage hello"

由于最近添加了 WSLg,因此不再需要弹出该命令 window。您只需使用 WSLg 调用 bash,就像这样(我目前在 WSL 中使用 Ubuntu):

wslg ~ -d Ubuntu bash

这将创建一个 BASH 会话,它将静静地坐在那里而不被人看到。或者,您可以像我一样做 运行 一些保持 运行ning 的服务。我创建了一个脚本来检查 运行ning 服务,如果它没有找到它们 运行ning,将 运行 它们。在 /usr/bin:

中创建文件

sudo touch /usr/bin/start-wsl-services

须藤纳米/usr/bin/start-wsl-services

将以下内容粘贴到文件中:

#!/bin/bash

# Check for and run System-wide DBus service.
SERVICE="dbus-daemon"
if pgrep -x "$SERVICE" >/dev/null
then
    pgrep -a "$SERVICE"
else
    sudo /etc/init.d/dbus start
    pgrep -a "$SERVICE"
fi

# Check for and run CUPS Printing Service.
SERVICE="cupsd"
if pgrep -x "$SERVICE" >/dev/null
then
    pgrep -a "$SERVICE"
else
    sudo /etc/init.d/cups start
    pgrep -a "$SERVICE"
fi

# Check for and start Freshclam CLAMAV Update service.
SERVICE="freshclam"
if pgrep -x "$SERVICE" >/dev/null
then
    pgrep -a "$SERVICE"
else
    sudo /etc/init.d/clamav-freshclam start
    pgrep -a "$SERVICE"
fi

# Check for and start SANED Scanner service.
SERVICE="saned"
if pgrep -x "$SERVICE" >/dev/null
then
    pgrep -a "$SERVICE"
else
    sudo /etc/init.d/saned start
    pgrep -a "$SERVICE"
fi

# Check for and start screen-cleanup service.
SERVICE="screen-cleanup"
if pgrep -x "$SERVICE" >/dev/null
then
    pgrep -a "$SERVICE"
else
    sudo /etc/init.d/screen-cleanup start
    pgrep -a "$SERVICE"
fi

# Check for and start Preload service.
SERVICE="preload"
if pgrep -x "$SERVICE" >/dev/null
then
    pgrep -a "$SERVICE"
else
    sudo /etc/init.d/preload start
    pgrep -a "$SERVICE"
fi

# Prestart LibreOffice twice for faster loading.
#/usr/bin/libreoffice --terminate_after_init
#sleep 5
#/usr/bin/libreoffice --terminate_after_init

# Check for error, make sure all functions called and run, and pass the result on to calling process.
if [[ $? -ne 0 ]] ; then
    exit 1
else
    exit 0
fi

保存并退出文件,然后使其可执行:

sudo chmod +x /usr/bin/start-wsl-services

然后我使用 运行 在启动时作为启动脚本的快捷方式调用它。或者您可以手动 运行 它。我在启动脚本中使用的命令是:

C:\Windows\System32\wslg.exe -d Ubuntu -- /usr/bin/start-wsl-services

我使用的启动命令脚本(名为StartWSL.cmd)如下:

@echo off

echo Starting WSL Linux...

:RETRY

C:\Windows\System32\wslg.exe -d Ubuntu -- /usr/bin/start-wsl-services

REM - C:\Windows\System32\bash.exe -c '/usr/bin/start-wsl-services'

IF %ERRORLEVEL% NEQ 0 (GOTO RETRY)

REM - Allow time to see all results.
timeout /t 5 /nobreak >NUL

REM - Uncomment below line for troubleshooting.
REM - pause

exit 0

这就是我现在在 Windows 11 时将 WSL 运行ning 置于后台的方式,类似于我在 Windows 10 时的做法。