在批处理脚本中将带或不带空格的文件路径传递给 cygwin ..“'\混淆

Passing filepath with or without spaces to cygwin inside a batch script.. " ' \ confusion

经过数小时和无数次在我能想到的任何地方放置 "s 和 ',并试图找到有关如何准确处理我正在尝试做的事情的资源,我迷失在比以前更多的困惑中我开始尝试.. 不幸的是,我对 windows.

中的批处理脚本非常不熟悉

我正在尝试编写一个批处理脚本,它将 windows 文件路径作为可以包含 spaces 的参数或不。然后应该将该文件路径传递给 cygwin 中的命令,然后将输出(只是修改后的文件路径)(仍然是 windows 文件路径)分配给一个变量在批处理脚本中。

如果文件路径没有 spaces,我可以完全使用它。但是我不知道如何使用 spaces。我看到“s 神奇地出现,\s 有时消失,有时不... 我能得到的最远的是:

@echo off
set "a=%1"
for /f "delims=" %%i in ('C:\cygwin64\bin\bash --login -c "echo '%a%'"') do set "newpath=%%i"
echo %newpath%
pause

对于文件路径 没有 spaces(注意 %a% 左右)。对于 with spaces 的路径,我得到一个语法错误,如

-c: line 0: unexpected EOF while searching for `''
-c: line 1: syntax error: unexpected EOF

(翻译,因为我的系统不是英文的)。如果我删除 %a% 附近的 's,文件路径中的所有 \s 都会消失(正如 cygwin echo 所预期的那样)并且 spaced 文件路径在第一个 space 之后被切断。 如果我用 "s 代替 's,就像这样

@echo off
set "a=%1"
for /f "delims=" %%i in ('C:\cygwin64\bin\bash --login -c "echo "%a%""') do set "newpath=%%i"
echo %newpath%
pause

然后它 适用于路径 spaces,但不适用于没有的路径(所有 \s 消失) . 在这一点上,我很困惑发生了什么。

显然我想将文字 'windows\file\path' 包括单引号传递给 cygwin,从那时起,批处理 's is treated literal. According to some online source ' 中的所有内容都没有特殊含义,除了我写的 /f 的特殊含义。但是,即使我删除 for /f 和变量赋值,并尝试直接回显,我也会得到类似的奇怪行为,这对我理解任何东西都没有帮助。

任何人都可以提供帮助,我如何实现我想要做的事情(上面写成斜体)?


编辑

做了一些进一步的测试,我想我现在明白了行为,但我仍然不知道如何实现我想要的。

所以,在批处理脚本中,如果我传递一个没有 space 的路径,变量包含

C:\some\path\without\space

但是如果我通过 space 的路径,变量包含

"C:\some\path with space"

即在第二种情况下,"s 包含在变量中。因此,如果我将前者传递给 cygwin echo,我会得到

echo C:\some\path\without\space

这将输出

C:somepathwithoutspace

符合预期。如果我通过第二个版本

echo "C:\some\path with space"

输出是

C:\some\path with space

再次如预期。同样,如果我添加 "s around the variable in the batch script, cygwin echo will just have those additional "s 也通过了,这会导致交换行为,非 space 路径会正确输出,而带有 spaces 的路径会失败,因为 "" 只是bash.

中的空字符串

恕我直言,这种行为非常……愚蠢。为了实现我想要的,我需要以某种方式确定变量的内容是否已经被引用,并在必要时添加引号。


可能不重要,但是要回答评论中的一个问题,我想做的当然不仅仅是使用echo,而是各种bash脚本用我传递给它的路径做一些事情。 最后,我想要一个程序,我可以在 windows 中快速 运行 / 可能会添加到我的上下文菜单中,所以在 cygwin bash 中做所有事情都违背了使最终程序可用的目的一种快速的方式,或者至少我不知道该怎么做。 我没有在批处理脚本中做所有事情的原因是我根本不知道批处理脚本,我只是使用我必须的最低限度来制作一个快速访问的程序;在做 bash 中的精髓时,因为我已经知道怎么做了。

例如我在某处有一个 .zip 文件,我想将其解压、计数文件、对文件执行 运行 一些 linux 命令(如转换)、分析文件名、修改文件名,最后运行 另一个 windows 程序处理修改后的文件。 中间步骤已经需要一些 linux 工具;加上所有文件处理,我不知道如何批量处理,但在 bash..

中非常容易

我唯一的问题是这个问题,因为我想 运行 任何目录中的最终程序,我想在其中使用该程序的存档恰好是,即它可以有也可以没有 spaces 在文件路径中。

结果我只需要像这样读取传递的文件路径

@echo off
set "path=%~1"
for /f "delims=" %%i in ('C\cygwin64\bin\bash --login -c "./some/script.sh ""%path%"""') do set "outvar=%%i"
:: do more things ..

我用过的地方

%~1

而不是

%1

阅读我的文件路径参数。这可以防止变量内容中出现任何 "s,因此在将它传递给 cygwin 时,我总是可以通过使用

转义双引号来添加文字引号
""