$ PATH环境变量中的百分比


16

我的$ PATH看起来像这样:

/home/torbjorr/deployed/vector/x86_64-GNU%2fLinux:/home/torbjorr/deployed/typewriter/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mustudio/x86_64-GNU%2fLinux:/home/torbjorr/deployed/mathext/x86_64-GNU%2fLinux:/home/torbjorr/deployed/doxymax/x86_64-GNU%2fLinux:/home/torbjorr/deployed/c2tex/x86_64-GNU%2fLinux:/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand:/home/torbjorr/deployed/x86_64-GNU%2fLinux/spellesc:/home/torbjorr/deployed/x86_64-GNU%2fLinux/projinit:/home/torbjorr/deployed/x86_64-GNU%2fLinux/herbs:/home/torbjorr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

在bash中,我可以毫无问题地调用位于

/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand

喜欢

$ wand
(i) Mål från "main.cpp" har registrerats
(i) Skapar katalog "__wand_targets_dbg"
(i) Kör g++ "main.cpp" -fpic -L"/home/torbjorr/deployed"  -g -Wall -std=c++11 -I"/home/torbjorr/deployed" -o "__wand_targets_dbg/cb-template

但是,在bourne shell兼容模式下,找不到魔杖:

$ wand
sh: 2: wand: not found

看来问题出在这些路径中的%符号。该符号已通过URL编码添加,因此即使名称不是有效的文件名,也可以在目录名称中使用名称“ GNU / Linux”。是否可以在sh中使用该名称,或者使sh命令作为bash使用。也就是说,即使使用/ bin / sh命令调用了bash,make bash的行为也一样,该命令还是链接到bash。


好问题。看来,“%”字符不是从$ PATH正常工作sh(这是确定的bashzsh虽然)。直接调用可执行文件在sh; 真的很奇怪
Rmano 2014年

如果使用2 %%会怎样?
mikeserv

还是逃避%?
mdpc

Answers:


15

这不是Bourne外壳,也不是Bourne外壳,而是bashAlmquist外壳,在您的情况下,可能是Debian Almquist外壳(BSD的Debian的Linux分支基于原始的Almquist外壳sh本身)。

在Almquist shell(原始版本和现代版本)中,%用于PATH特定于的额外功能ash。引用文档:

路径搜寻

查找命令时,shell首先查看其名称是否具有shell函数。然后,如果PATH不包含的条目 %builtin,它将通过该名称查找内置命令。最后,它依次搜索PATH中的每个条目。

PATH变量的值应该是一系列用冒号分隔的条目。每个条目都包含一个目录名,或一个目录名,后跟一个以百分号开头的标志。当前目录应以空目录名称表示。如果没有百分号,则该条目使外壳程序在指定目录中搜​​索命令。如果该标志为,%builtin 则搜索shell内置命令列表。如果标志是, %func 则在目录中搜索一个文件,该文件将作为shell的输入读取。该文件应定义一个函数,该函数的名称为要搜索的命令的名称。

只需执行包含斜杠的命令名称,而无需执行上述任何搜索。

其他shell类似于kshzsh具有类似的自动加载功能机制,但是它们使用不同的变量($FPATH),但是您无法定义哪个函数或可执行文件优先。

在您的情况下,/home/torbjorr/deployed/vector/x86_64-GNU%2fLinux被解释为/home/torbjorr/deployed/vector/x86_64-GNU带有2fLinux标志的目录。该标志被忽略,因为它是未知的。

没有办法解决。即使灰烬具有逃逸机制,因此%无法对其进行特殊处理,它也无法在其他外壳或其他$PATH类似的东西中工作execvp()

您需要从中删除%字符$PATH,因此重命名目录或添加符号链接。

或者不使用ash你的/bin/sh。其他没有实现的轻量级POSIX shell实现包括yashmksh


尽管此答案给出了解释,但没有给出解决方案。是否有保留%的兼容方式。
user877329 2014年

@ user877329,这里没有真正的解决方案。看到我的编辑。
斯特凡Chazelas

3
换句话说,Debian sh违反了POSIX标准。鉴于拥有一个单独的点sh就是您应该确保不要跳过某些不兼容的shell扩展(我想/bin/sh这些天没人会使用它作为登录shell),我认为这是一个错误。
celtschk 2014年

1
@celtschk同意,尽管使用ash/ bin / sh的目的更多是为了避免使用using带来的性能损失bash,所以使用yashor mksh(或posh如果要排除所有扩展名)仍然比使用更好bash。另外,可能会认为这是一个极端的情况。通常没有人会%包含路径组件。大多数外壳都有不兼容POSIX的特殊情况。
斯特凡Chazelas

1
@mtmiller,这不是我读取便携式文件名字符集(PFCS)的含义的方式。POSIX指定编程API,但不指定文件系统实现。PFCS是最低的POSIX保证,无论文件系统如何,无论当前语言环境如何,它都可以工作,但是如果文件系统支持并在当前语言环境中有效,则该工具不能作为不接受文件名中字符的工具。注意,例如POSIX要求有一个[命令,即使该字符不在PFCS中也是如此。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.