如何将带有空格的文件名从 WSL 传递到 cmd.exe?

如何将带有空格的文件名从 WSL 传递到 cmd.exe?

答案超级用户.com/a/1252579/143180描述了一个 WSL shell 命令,它将在 Windows 的默认应用程序中打开一个文件。

cmd.exe /c start <file>

如果文件名包含空格,则此命令将无法打开该文件。而是在新窗口中打开 Windows 命令行。

我们如何修改此命令以从 WSL shell 打开 Windows 默认应用程序中的文件?在这种情况下是否有更有效的命令可用?

我已经测试了此命令的变体,包括在文件名周围加上引号(和"") ,转义空格,转义引号,以及在上面答案的评论中找到的''命令的类似变体。"%localappdata%/lxss/$(readlink -f $some_relative_path)"

答案1

不幸的是,据我所知,没有一个答案可以 100% 适用于所有环境。

最好的- 使用 bash 解析完整路径

我建议将其保存为 shell 脚本,放在文件夹中$PATH。它接受完整路径和相对路径,甚至多个文件,然后将其提供给所需的二进制文件。在本例中cmd.exe

#!/usr/bin/env bash
OIFS="$IFS"
IFS=$' \t\n'

if [[ "$@" =~ \/mnt\/([a-zA-Z]+)\/ ]]; then 
    cmd.exe /c start '' "${@/$BASH_REMATCH/${BASH_REMATCH[1]}\:\/}"
else
    cmd.exe /c start '' "$@"
fi

\/mnt第 5 行的部分\/mnt\/([a-zA-Z]+)\/与您的词根相对应。因此,如果您的词根不同,请相应地设置正则表达式。

选项 2 - 创建函数

作为别名,简短但更不可靠。

alias cmd="cmd.exe /c start '' "${@//&/^&}""
或者

将其保存在你的一个 shell 中,例如:bash .bashrc.*rc 文件。

cmd() {
IFS=$' \t\n'
cmd.exe /c start '' "$@"
}

如果您从当前 shell 调用文件,此方法有效。因此,它需要您当前目录的相对路径,并使用正斜杠转义空格。如果您的文件位于文件./org夹中。

例如:cmd org/Read\ me\ Official.html

为了使其始终与特定文件夹相关,$HOME您可以附加

cd $HOME && cmd.exe /c start '' "$@"

此选项甚至接受记事本之类的程序和名称中带有空格的文件。

例如:cmd onenote another\ file.txt

另一种方法cmd.exe /c start '' "$@"rundll32.exe url,OpenURL '' "$@"根据您的 shell 进行不同的解析。

选项 3 - 凑合一下

您可以将 xdg-open 与wsl-open一个脚本,允许您使用 Windows 二进制文件作为默认设置,并完成一些繁重的解析工作。

或者wslpath在函数中使用来获取真实路径。

cmd() {
  CMD=$1
  shift;
  ARGS=$@
  WIN_PWD=`wslpath -w "$(pwd)"`
  cmd.exe /c "pushd ${WIN_PWD} && ${CMD} ${ARGS}"
}

无论如何,这都是一件令人头疼的事。

答案2

我在起草时找到了这个问题的答案。此命令似乎有效:

cmd.exe /c start "open file" "<file name>"

尝试解释

来自启动帮助文件

启动程序,命令或批处理脚本(在新窗口中打开。)[重点补充。]

句法

START "title" [/D path] [options] "command" [parameters]

始终包含一个标题,可以是一个简单的字符串,如“我的脚本”,也可以是一对空引号“”

根据 Microsoft 文档,标题是可选的,但根据所选的其他选项,如果省略标题,则可能会遇到问题。

如果我们传递的第一个参数start是带引号的字符串,则命令会将此参数解释为窗口 TITLE。如果第一个参数未带引号,则命令会假定我们跳过了 TITLE 参数。因此,带引号的文件名作为第一个且唯一的参数将无法打开文件。

添加任何带引号的 TITLE 参数似乎都会产生一个有效的命令。

相关内容