如何在 UNIX 上的 $PATH 中转义冒号 (:)?

Posted

技术标签:

【中文标题】如何在 UNIX 上的 $PATH 中转义冒号 (:)?【英文标题】:How to escape colon (:) in $PATH on UNIX? 【发布时间】:2013-01-17 15:43:30 【问题描述】:

我需要在我的应用程序中解析$PATH 环境变量。 所以我想知道$PATH 中哪些转义字符是有效的。 我创建了一个名为/bin:d 的测试目录并创建了一个名为 funny 在里面。如果我用绝对路径调用它,它就会运行。 我只是不知道如何在$PATH 中逃脱: 我尝试逃脱 带有\ 的冒号并将其包装成单' 和双" 引号。 但是当我运行which funny 时总是找不到它。 我正在运行 CentOS 6。

【问题讨论】:

解决办法:创建符号链接? @KarolyHorvath:是的,或者重命名目录。但我认为 OP 没有使用它,他正在尝试模拟 shell 的算法来解析 PATH 并且只想知道是否有转义规则来自己实现它。 which发壳? 您可以使用名称中带有: 的目录来强制人们输入命令的路径名作为完整路径名。这甚至可能是一个合法的策略,以确保敏感命令不会被诱杀(susudo 突然想到);想要执行它们的用户必须使用cd 进行旋转或键入完整路径名,因为目录不能在路径上。 (当然,符号链接可以解决这个问题,所以它不是完美的保护。) 处理这种情况的合理方法本来可以(如果他们选择这样做...),如果您想要冒号,你给一个双冒号。在PATH 中,/usr/c: 将变为/usr/c::。有没有人真正需要一个支持 empty 条目的PATH 【参考方案1】:

根据 POSIX 标准,这是不可能的。这不是特定 shell 的函数,PATH 处理是在 C 库中的 execvp 函数中完成的。没有任何形式的引用的规定。

这就是为什么强烈建议不要包含某些字符(不在“可移植文件名字符集”中的任何字符 - 冒号作为示例。)的原因。

来自SUSv7:

由于<colon> 在此上下文中是分隔符,因此可能在 PATH 中使用的目录名称不应包含 <colon> 字符。

另见source of GLIBC execvp。我们可以看到它使用 strchrnulmemcpy 函数来处理 PATH 组件,绝对没有提供跳过或取消转义任何类型的转义字符。

【讨论】:

这是否适用于其他类似 PATH 的变量?例如。 PKG_CONFIG_PATH、MAN_PATH 等 @olejorgenb 这些不是由标准定义的,因此取决于使用它们的应用程序如何定义它。【参考方案2】:

看函数 extract_colon_unit 在我看来,这是不可能的。 : 是无条件的并且 不可避免地用作路径分隔符。

嗯,这至少对 bash 是有效的。其他外壳可能会有所不同。

【讨论】:

另外,会不会是苹果的实现遗漏了什么? @Shahbaz:不,看文件的标题。它不是苹果对bash 的重新实现,它是 GNU 的——还有谁?它只是托管在那里,因为 Apple OS 使用 bash 并且 GPL 要求它显示源代码。您可以在很多地方找到这个完全相同的文件的副本。 也许这在较新版本的 Bash 中有所改变?您链接的代码很旧。 既然您查看了源代码,我想您是对的。我想知道为什么他们没有实现转义序列,因为冒号是一个常见字符。我认为它们可能是一些 posix 范围的规范,但似乎不是。 @PhilippWendler:实际上,链接仅供参考。我从我的 Archlinux 下载了最新的 - 运行 makepkg -o。是bash-4.2.042,这个功能也是一样的。【参考方案3】:

你可以试试mounting它

mount /bin:d /bind
PATH=/bind

【讨论】:

【参考方案4】:

根据http://tldp.org/LDP/abs/html/special-chars.html 单引号应该保留所有特殊字符,所以如果不尝试,我认为'/bin:d' 可以在$PATH 中工作。

【讨论】:

这里描述的是bash如何解析表达式,与PATH环境变量的处理方式完全无关。

以上是关于如何在 UNIX 上的 $PATH 中转义冒号 (:)?的主要内容,如果未能解决你的问题,请参考以下文章

在 YAML 中转义冒号

如何在 django 中转义 ^

如何在 robots.txt Disallow 指令中转义 $?

将SQL for xml path('')中转义的字符正常显示

如何在 Presto 中转义单引号?

如何在 MySql 中转义撇号(')?