当前位置: 首页>>技术教程>>正文


bash – 如何保护传递给 cd 命令的括号?

, , ,

问题描述

我问here如何让cd保护空格。 Tab 完成功能很棒,但有时您会从剪贴板粘贴路径,所以这很有用。

但是,该解决方案以括号中断。无论您如何尝试转义和保护输入,它始终会返回:

bash: syntax error near unexpected token `('

有没有办法让它也处理括号?我想要的是,当我输入它时,它起作用了:

cd My path with spaces (and parentheses)

最佳答案

在参数周围使用单引号 '。 (这适用于任何命令,而不仅仅是 cd )。

cd 'My path with spaces (and parentheses)'

您不能让 bash 将括号传递给 cd 。让空间发挥作用是一项非常专业的技巧。

除了 ' 本身,单引号围绕每个字符。用 4 个字符的序列 '\\'' 替换单引号。

cd 'Apostrophe'\''s a pain'

如果目录名称以连字符开头,这将不起作用,因为这会导致 cd 命令将参数解释为选项。在目录名称前传递 -- 以避免这种情况。

有关详细信息,请参阅 https://unix.stackexchange.com/questions/69144/how-do-i-escape-a-sub-directory-name-with-an-ampersand-in-it/69147#69147

另一种方法是让 shell 读取单独的文本行,而不是在命令行上传递参数。

Strapakowsky@darkstar ~$ read -r; cd -- "$REPLY"
My path with spaces (and parentheses)
Strapakowsky@darkstar ~/My path with spaces (and parentheses)$ 

与其手动 copy-paste,不如以编程方式执行。安装 xclipxsel

cd -- "$(xclip -o -selection clipboard)"
cd -- "$(xsel -bo)"

您可以将其设为别名。

alias cde='cd -- "$(xsel -bo)"'

次佳答案

如何将 cd 正确设置为名称中包含空格和括号等字符的目录:

如果您的文件夹名称不包含 single-quote 字符 ' ,只需将其用单引号引起来:

cd 'My path with spaces (and parentheses)'

如果它确实包含 ' ,但不包含双引号字符 " 、反斜杠 \\ 、反引号 ` 或美元 $ ,请将其括在双引号中:

cd "My path with spaces (and parentheses)"

文件名或目录名同时包含单引号和双引号的情况并不常见。 (这可能是因为文件名或目录名根本不包含双引号。我最初不推荐使用双引号的唯一原因是,与单引号不同,双引号允许 $ 扩展环境变量. 如果您的文件名包含 $ 字符后跟文本,这将是一个问题。)

如果它包含两者,或者您只想要另一种方法,那么您可以通过在它之前插入反斜杠字符 \\ 来手动转义每个空格和括号:

cd My\ path\ with\ spaces\ \(and parentheses\)

这很烦人,但幸运的是,如果您键入名称的开头并按 Tab ,shell 会为您完成。如果有多个以 My 开头的文件或目录名称,那么您可能需要输入更多内容才能展开。如果您按 Tab 但它没有展开,您可以再次按 Tab 以查看与您目前输入的内容相匹配的文件列表。然后您就会知道必须输入多少内容才能使其唯一匹配并展开。

或者,您可以转义内部引号。例如,假设您有一个名为:

Mischa's gardening tips for "home and office"

您可以使用:

cd Mischa\'s\ gardening\ tips\ for\ \"home\ and\ office\"

但您也可以简单地使用:

cd 'Mischa'\''s gardening tips for "home and office"'

反斜杠在单引号内并不特殊,所以我们终止 single-quoted 字符串,附加一个 backslash-protected 单引号,然后立即开始另一个 single-quoted 字符串,所有这些都没有任何可以开始单独参数的空格。

为什么您可能无法使 cd 按您希望的方式工作:

至于让 cd My path with spaces (and parentheses) 工作:不,你真的不能那样做,因为这种行为不是特定于 cd 命令的,它是运行任何命令的工作方式的一部分。运行命令时,它会给出用户提供的参数列表。当 shell 看到空格时,它知道一个参数刚刚结束而另一个参数刚刚开始。要将空格作为参数的一部分传递,必须以上述方式之一引用它。

有时您可以实现其中的一部分——您可以使 cd My path with spaces 工作以进入 My path with spaces 文件夹。您可以通过编写一个 shell 脚本来实现这一点,该脚本将其所有 user-provided 参数与空格连接起来。 (然后,如果您愿意,可以通过为其创建一个名为 cd 的 shell 别名,使 cd 本身调用该脚本;这将优先于您当前通常运行的内置 cd 的 shell。)但是:

  • 该脚本不会收到 My path with spacesMy path with spaces 的不同参数,因此 cd My path with spaces 会失败或输入错误的文件夹。

  • 您不能对括号执行此操作,因为它们被 shell 用于分组,因此它们不会以任何方式与命令通信。实际上,大多数时候 shell 只会抛出语法错误(正如您所见):

    \n

    ek@Kip:~$ cd My path with spaces (and parentheses)\nbash: syntax error near unexpected token `('\n

    \n

    无论您更改什么,在给出该命令时该语法错误将继续发生。

我说您 “probably” 无法完成这项工作,因为有一种方法可以做到——您可以制作自己的 shell,其行为如您所愿。但这是极其困难的,不太可能有人愿意这样做,只是为了做出这种改变。 (您也可以修改现有 shell 的源代码,这是一个更实用的解决方案,但仍然需要比大多数人想要付出更多的努力。)除此之外,cd 不太可能接受包含任意字符(包括空格)的目录名它们,就像在 Windows 上一样。

如果您想知道为什么这适用于 Windows 但不适用于 Ubuntu:在 Windows 中,命令将在它们之后键入的文本作为文本字符串传递,并且当命令需要将该字符串解释为一系列单独的参数(其中通常,但并非总是如此),该命令的代码必须调用一个特殊的库函数来解析 命令行 字符串。 (在 C 程序中,这发生在幕后,但仍涉及使用 Windows API。)

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/13605.html,未经允许,请勿转载。