问题描述
我问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
命令将参数解释为选项。在目录名称前传递 --
以避免这种情况。
另一种方法是让 shell 读取单独的文本行,而不是在命令行上传递参数。
Strapakowsky@darkstar ~$ read -r; cd -- "$REPLY"
My path with spaces (and parentheses)
Strapakowsky@darkstar ~/My path with spaces (and parentheses)$
与其手动 copy-paste,不如以编程方式执行。安装 xclip 或 xsel。
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 spaces
和My 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。)