$PATH 环境变量中的百分比

use*_*329 16 shell path dash ash

我的 $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
Run Code Online (Sandbox Code Playgroud)

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

/home/torbjorr/deployed/x86_64-GNU%2fLinux/wand
Run Code Online (Sandbox Code Playgroud)

喜欢

$ 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
Run Code Online (Sandbox Code Playgroud)

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

$ wand
sh: 2: wand: not found
Run Code Online (Sandbox Code Playgroud)

问题似乎是这些路径中的 % 符号。此符号已通过 URL 编码添加,因此名称“GNU/Linux”可以在目录名称中使用,即使它不是有效的文件名。是否可以让名称在 sh 中工作,或者使 sh 命令作为 bash 工作。也就是说,即使使用 /bin/sh 命令调用 bash 的行为也相同,该命令无论如何都指向 bash 的符号链接。

Sté*_*las 15

那不是 Bourne shell,也不是bash模拟Bourne shell,而是Almquist shell,在您的情况下可能是 Debian Almquist shell(Debian 的一个 Linux 分支,BSD 的 sh 本身基于原始的 Almquist shell)。

在 Almquist shell(原始版本和现代版本)中,%用于PATH特定于ash. 从文档中引用:

路径搜索

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

PATH 变量的值应该是一系列由冒号分隔的条目。每个条目都包含一个目录名,或者一个目录名后跟一个以百分号开头的标志。当前目录应由空目录名称指示。如果不存在百分号,则该条目会导致 shell 在指定目录中搜​​索命令。如果标志是,%builtin 则搜索 shell 内置命令列表。如果标志是, %func 则在目录中搜索作为 shell 输入读取的文件。此文件应定义一个函数,其名称是要搜索的命令的名称。

包含斜杠的命令名称将直接执行而不执行任何上述搜索。

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

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

没有办法解决这个问题。即使 ash 有一个逃逸机制,所以它%不会被特殊对待,它也不会在其他 shell 或其他看起来$PATHexecvp().

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

或者不要ash用于您的/bin/sh. 其他不这样做的轻量级 POSIX shell 实现包括yashmksh.

  • 换句话说,Debian `sh` 违反了 POSIX 标准。鉴于拥有一个单独的 `sh` 的目的正是你应该确保不要被一些不兼容的 shell 扩展绊倒(我猜现在没有人使用 `/bin/sh` 作为登录 shell),我认为漏洞。 (3认同)