batch-file - 在批处理脚本中将带或不带空格的文件路径传递给cygwin ..“'\混淆
问题描述
经过数小时和无数次将“s 和 's 放在我能想象到的任何地方并试图找到关于我正在尝试做的事情的处理方式的资源之后,我迷失在比开始尝试之前更多的困惑中......不幸的是,我对 Windows 中的批处理脚本非常不熟悉。
我正在尝试编写一个批处理脚本,该脚本将windows文件路径作为参数,可以包含空格或不包含空格。然后应该将该文件路径传递给 cygwin 中的命令,然后将输出(只是修改的文件路径(仍然是Windows文件路径))分配给批处理脚本中的变量。
如果文件路径没有空格,我让它完全工作..但我不知道如何用空格来做。我看到 "s 神奇地出现,\s somtimes 消失,有时没有......我能得到的最远的是:
@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
这仅适用于没有空格的文件路径(注意 %a% 左右)。对于带有空格的路径,我收到一个语法错误,例如
-c: line 0: unexpected EOF while searching for `''
-c: line 1: syntax error: unexpected EOF
(翻译因为我的系统不是英文的)。如果我删除 %a% 附近的 's,文件路径中的所有 \s 都会消失(正如 cygwin echo 所预期的那样),并且在第一个空格之后隔开的文件路径被切断。如果我用 "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
那么它仅适用于带有空格的路径,但不适用于没有空格的路径(所有 \s 消失)。在这一点上,我很困惑发生了什么。
显然,我想将包含单引号的文字 'windows\file\path' 传递给 cygwin,因为那时 's 内的所有内容都被视为文字。根据一些在线资源 ' in batch 没有特殊含义,除了我写的这个特殊的 for /f 。但是,即使我删除了 for /f 和变量赋值,并尝试直接回显,我也会得到类似的奇怪行为,这无助于我理解任何事情。
谁能帮忙,我该如何实现我想要做的事情(上面用斜体写)?
编辑
做了一些进一步的测试,我想我现在理解了这种行为,但我仍然不知道如何实现我想要的。
所以,在批处理脚本中,如果我传递一个没有空格的路径,变量包含
C:\some\path\without\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,cygwin echo 只会传递那些额外的 "s,这会导致交换行为,非空格路径正确输出,而带有空格的路径失败,因为"" 只是 bash 中的空字符串。
恕我直言,这种行为非常……愚蠢。为了实现我想要的,我需要以某种方式确定变量的内容是否已经被引用,并在必要时添加引号。
可能并不重要,但要回答评论中的一个问题,我想做的当然不仅仅是使用 echo,而是各种 bash 脚本,它们对我传递给它的路径做一些事情。最后,我想要一个可以在 Windows 中快速运行的程序 / 可能会添加到我的上下文菜单中,因此在 cygwin bash 中执行所有操作都违背了使最终程序快速可用的目的,或者至少我不知道如何至。我不在批处理脚本中做所有事情的原因是我根本不知道批处理脚本,我只是使用我必须的最低限度来制作一个快速访问的程序;在 bash 中做精髓,因为我已经知道如何做。
例如,我在某处有一个 .zip 文件,我想对其进行解压缩、计数文件、在文件上运行一些 linux 命令(如转换)、分析文件名、修改文件名,最后在修改后运行另一个 Windows 程序文件。中间步骤已经需要一些 linux 工具;加上所有文件处理,我不知道如何批量处理,但在 bash 中很容易..
我唯一的问题是这个问题,因为我想在我想要使用该程序的存档所在的任何目录中运行最终程序,即它可以或不可以在文件路径中有空格。
解决方案
结果我只需要像这样读取传递的文件路径
@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 时,我总是可以添加文字引号,方法是使用转义双引号
""
推荐阅读
- java - Java IntelliJ 即使使用正确的 JDK,也没有此类文件异常
- javascript - 如何将颜色框保存到本地存储中?
- c# - C# 列表查找“对象”
- windows - 使用批处理文件编辑字符串中的单词
- sirikit - 如果任何整数参数 == 0,INShortcut 是否会失败?
- hadoop - 在 Apache Hadoop 中的 Datanode 内重新平衡磁盘
- android - 闪屏覆盖 PreferenceActivity
- php - 如何将表单中的数据插入数据库并获取最后插入的 ID/在 CI 中创建 uniqueID 作为用户的 Session
- java - 当我需要计算股权回报时,嵌套循环给了我相同或错误的答案
- python - 我应该使用等待popen吗