如何在 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
发壳?
您可以使用名称中带有:
的目录来强制人们输入命令的路径名作为完整路径名。这甚至可能是一个合法的策略,以确保敏感命令不会被诱杀(su
和 sudo
突然想到);想要执行它们的用户必须使用cd
进行旋转或键入完整路径名,因为目录不能在路径上。 (当然,符号链接可以解决这个问题,所以它不是完美的保护。)
处理这种情况的合理方法本来可以(如果他们选择这样做...),如果您想要冒号,你给一个双冒号。在PATH
中,/usr/c:
将变为/usr/c::
。有没有人真正需要一个支持 empty 条目的PATH
?
【参考方案1】:
根据 POSIX 标准,这是不可能的。这不是特定 shell 的函数,PATH 处理是在 C 库中的 execvp 函数中完成的。没有任何形式的引用的规定。
这就是为什么强烈建议不要包含某些字符(不在“可移植文件名字符集”中的任何字符 - 冒号作为示例。)的原因。
来自SUSv7:
由于
<colon>
在此上下文中是分隔符,因此可能在 PATH 中使用的目录名称不应包含<colon>
字符。
另见source of GLIBC execvp。我们可以看到它使用 strchrnul
和 memcpy
函数来处理 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】:
你可以试试mount
ing它
mount /bin:d /bind
PATH=/bind
【讨论】:
【参考方案4】:根据http://tldp.org/LDP/abs/html/special-chars.html 单引号应该保留所有特殊字符,所以如果不尝试,我认为'/bin:d' 可以在$PATH 中工作。
【讨论】:
这里描述的是bash如何解析表达式,与PATH环境变量的处理方式完全无关。以上是关于如何在 UNIX 上的 $PATH 中转义冒号 (:)?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 robots.txt Disallow 指令中转义 $?