带空格的 Bash 变量

Posted

技术标签:

【中文标题】带空格的 Bash 变量【英文标题】:Bash variables with spaces 【发布时间】:2011-08-14 17:37:45 【问题描述】:

我在 Windows 下的 MinGW shell 中面临下一个问题。我在我的/etc/profile 中有这个表达式:

export GIT_SSH="/c/Program Files/TortoiseGit/bin/TortoisePlink.exe"

当我在本地存储库上使用 git fetch 时,这不起作用。但如果我这样做(旧的 DOS 方式),它可以工作:

export GIT_SSH="/c/Progra~1/TortoiseGit/bin/TortoisePlink.exe"

我的问题是:

如何使用变量中的空格使其工作?

出于测试目的,您可以模拟这样的事情(任何示例都很好):

export VAR="/c/Program Files/TortoiseGit/bin/TortoisePlink.exe"
# and try to execute like this
$VAR

有没有解决方案(除了前面提到的)?

【问题讨论】:

当您尝试/c/Program\ Files/TortoiseGit/bin/TortoisePlink.exe 时会发生什么?也就是说,包含一个反斜杠来转义空格。 如下所示 - 它不工作 @chrisaycock:我也被骗了,但这只是避免在导出命令的参数中使用双引号的一种方法。之后这个字符串以同样的方式处理,空格仍然是空格:-) 【参考方案1】:

像这样执行它:"$VAR"。这是 shell 脚本中最重要的问题之一,因为字符串总是按字面意思替换,并且任何包含的空格都被视为标记分隔符而不是字符串的字符。将变量替换为运行时粘贴的一种代码。

当您编写 $VAR 时,真正发生的事情是 shell 尝试使用第一个参数 Files/TortoiseGit/bin/TortoisePlink.exe 执行二进制文件 /c/Program

我是通过在特定输入的大型 shell 脚本中遇到奇怪的语法错误才学会这一点的。如果运行时输入包含特殊字符,我能想到的任何其他语言都不会抱怨语法错误 - 但这是 shell 脚本的本质,因为 bash 和 sh 等命令解释器逐行解释代码。

当您希望字符串包含空格并且不想将其视为单独的标记时,请将其括在双引号中。

【讨论】:

@Iulian:那么你别无他法,只能更改其他脚本......或者坚持不带空格。 Git 最初是为类 Unix 操作系统设计的,带有空格的路径不符合他们的约定。 如果 git 调用它而不引用它,那么它是 GIT 错误,应该报告。【参考方案2】:

作为参考,我通过用转义引号封装参数解决了 osx 上的类似问题。这可能不是最好的解决方案,但似乎可行。

alias sub="\"/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl\""

【讨论】:

【参考方案3】:

我已经通过包含反斜杠来转义空格来解决它:

/Program Files 变为 /Program\ Files

示例:

export GIT_SSH=/c/Program\ Files/TortoiseGit/bin/TortoisePlink.exe

【讨论】:

虽然技术上可行,但如果你解释你做了什么,你可能会得到赞成票(而不是反对票)。与此作斗争的人不会理解你所给予的意义。 谢谢 Ed,这就是我需要的答案。 这是一个 hack 或充其量是一种解决方法,而不是 解决方案【参考方案4】:

使用 Git 2.23(2019 年第三季度,八年后),将 GIT_SSH 设置为 /c/Program\ Files/TortoiseGit/bin/TortoisePlink.exe 将...工作(对于仍在使用 Windows 7 的用户)!

见Johannes Schindelin (dscho)commit eb7c786(2019 年 7 月 16 日)。(由 Junio C Hamano -- gitster -- 合并于 commit a5194d8,2019 年 7 月 25 日)

mingw: 支持生成名称中包含空格的程序

在某些较旧的 Windows 版本(例如 Windows 7)上,CreateProcessW() 函数在其第一个参数 lpApplicationName 中并不真正支持空格。 但它支持将NULL 传递为lpApplicationName,这使得它可以从lpCommandLine 的(可能引用的)第一个参数中找出应用程序。

让我们使用这个技巧(如果我们确定第一个参数匹配 可执行文件的路径)以支持启动其路径包含的程序 空格。

这修复了git-for-windows/git issue 692


Git 2.24(2019 年第四季度)增加了一个测试:

参见Alexandr Miloslavskiy (SyntevoAlex) 的commit 71f4960(2019 年 10 月 1 日)。(由 Junio C Hamano -- gitster -- 合并到 commit 424663d,2019 年 10 月 9 日)

t0061:修复带有空格的 argv[0] 测试(仅限 MINGW)

该测试最初是针对用户报告在 Windows 上将 GIT_SSH 设置为带有空格的 .bat 文件失败的情况设计的:git-for-windows#692

【讨论】:

以上是关于带空格的 Bash 变量的主要内容,如果未能解决你的问题,请参考以下文章

在 Bash 中包含多个带引号的 args 的变量

为啥变量赋值中的空格会在 Bash 中出错? [复制]

在bash中将包含空格的变量传递给命令[重复]

Bash 在第一个空格后结束变量?

学习bash——变量

如何在:Django 中通过 URL 传递带空格的变量