ZSH:为什么内置数组“$commands”中没有一些命令?
ZSH: Why aren't some commands in the builtin array `$commands`?
我在谷歌上搜索如何验证命令的可用性。
在这个过程中,我找到了内置变量$commands
。
https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#index-commands
但是当我尝试时,有些命令不在 $commands
中,即使它们可用。
我想深入了解通过了解时间和条件来检查命令是否存在是否有用。
tl;博士
您可能移动或安装了从未 运行 或 shell 移动或安装后从未遍历命令位置的命令,并且作为结果是 $commands
访问的命令哈希 table 不是这些命令的最新信息。
如果您需要一种可靠的方法来检查命令是否存在,请使用 command -v
,请参阅此 answer。
如果您只想在命令散列中查看命令 table 运行 hash -r
或 rehash
(仅限 ZSH)。
上下文
什么是 $commands
?
您在问题中链接的文档中找到了这个:
This array gives access to the command hash table. The keys are the names of external commands, the values are the pathnames of the files that would be executed when the command would be invoked. Setting a key in this array defines a new entry in this table in the same way as with the hash builtin. Unsetting a key as in ‘unset "commands[foo]"’ removes the entry for the given key from the command hash table.
– https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#index-commands
“允许访问命令哈希 table”...让我们看看这是什么。
什么是“命令哈希 table”?
为此,我们将转到 ZSH 指南的 chapter 3,特别是第 1 节(外部命令)。
The only major issue is therefore how to find [external commands]. This is done through the parameters $path
and $PATH
[...].
There is a subtlety here. The shell tries to remember where the commands are, so it can find them again the next time. It keeps them in a so-called 'hash table', and you find the word 'hash' all over the place in the documentation: all it means is a fast way of finding some value, given a particular key. In this case, given the name of a command, the shell can find the path to it quickly. You can see this table, in the form key=value, by typing hash
.
In fact the shell only does this when the option HASH_CMDS
is set, as it is by default. As you might expect, it stops searching when it finds the directory with the command it's looking for. There is an extra optimisation in the option HASH_ALL
, also set by default: when the shell scans a directory to find a command, it will add all the other commands in that directory to the hash table. This is sensible because on most UNIX-like operating systems reading a whole lot of files in the same directory is quite fast.
– https://zsh.sourceforge.io/Guide/zshguide03.html
好的,所以我们现在知道 $commands
可以访问命令哈希 table,它本质上是一个位置缓存。这个缓存需要更新,对吧?
命令哈希 table 何时更新?
1.第一次找到命令时
我们从上面的文档中知道这一点:
The shell tries to remember where the commands are, so it can find them again the next time. It keeps them in a so-called 'hash table' [...].
HASH_CMDS
还有其他文档支持:
Note the location of each command the first time it is executed. Subsequent invocations of the same command will use the saved location, avoiding a path search.
2。当您的 shell 扫描目录寻找命令并找到其他命令时
同样,由于上述文档,我们知道这一点:
There is an extra optimisation in the option HASH_ALL
, also set by default: when the shell scans a directory to find a command, it will add all the other commands in that directory to the hash table.
好的,这就是所有的上下文。
回到问题,为什么?
为什么您要查找的命令没有出现在 $commands
数组中?为什么它们不在命令哈希中 table?
好吧,我们现在知道命令哈希 table 何时更新,因此我们可以推测不满足更新条件以及您可能处于何种情况的一些可能性:
- 第一次找到命令时
- 您最近安装了一个新命令,但从未 运行 安装它。
- 您已经移动了一个现有命令,但从未运行它。
- 当您的 shell 扫描目录以查找命令并找到其他命令时
- 您没有 运行 需要路径搜索的命令,该路径搜索会遍历安装您的 new/moved 命令的位置。
有什么可以做的吗?
这取决于你在做什么。
关键我知道命令的存在
不要使用 $commands
。使用 command -v <command_name>
,请参阅此 answer。
我只想在命令哈希中查看命令 table
您可以强制命令哈希 table 使用 hash -r
或在 ZSH rehash
.
中更新
进一步阅读
我在谷歌上搜索如何验证命令的可用性。
在这个过程中,我找到了内置变量$commands
。
https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#index-commands
但是当我尝试时,有些命令不在 $commands
中,即使它们可用。
我想深入了解通过了解时间和条件来检查命令是否存在是否有用。
tl;博士
您可能移动或安装了从未 运行 或 shell 移动或安装后从未遍历命令位置的命令,并且作为结果是 $commands
访问的命令哈希 table 不是这些命令的最新信息。
如果您需要一种可靠的方法来检查命令是否存在,请使用 command -v
,请参阅此 answer。
如果您只想在命令散列中查看命令 table 运行 hash -r
或 rehash
(仅限 ZSH)。
上下文
什么是 $commands
?
您在问题中链接的文档中找到了这个:
This array gives access to the command hash table. The keys are the names of external commands, the values are the pathnames of the files that would be executed when the command would be invoked. Setting a key in this array defines a new entry in this table in the same way as with the hash builtin. Unsetting a key as in ‘unset "commands[foo]"’ removes the entry for the given key from the command hash table.
– https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#index-commands
“允许访问命令哈希 table”...让我们看看这是什么。
什么是“命令哈希 table”?
为此,我们将转到 ZSH 指南的 chapter 3,特别是第 1 节(外部命令)。
The only major issue is therefore how to find [external commands]. This is done through the parameters
$path
and$PATH
[...].There is a subtlety here. The shell tries to remember where the commands are, so it can find them again the next time. It keeps them in a so-called 'hash table', and you find the word 'hash' all over the place in the documentation: all it means is a fast way of finding some value, given a particular key. In this case, given the name of a command, the shell can find the path to it quickly. You can see this table, in the form key=value, by typing
hash
.In fact the shell only does this when the option
HASH_CMDS
is set, as it is by default. As you might expect, it stops searching when it finds the directory with the command it's looking for. There is an extra optimisation in the optionHASH_ALL
, also set by default: when the shell scans a directory to find a command, it will add all the other commands in that directory to the hash table. This is sensible because on most UNIX-like operating systems reading a whole lot of files in the same directory is quite fast.
– https://zsh.sourceforge.io/Guide/zshguide03.html
好的,所以我们现在知道 $commands
可以访问命令哈希 table,它本质上是一个位置缓存。这个缓存需要更新,对吧?
命令哈希 table 何时更新?
1.第一次找到命令时
我们从上面的文档中知道这一点:
The shell tries to remember where the commands are, so it can find them again the next time. It keeps them in a so-called 'hash table' [...].
HASH_CMDS
还有其他文档支持:
Note the location of each command the first time it is executed. Subsequent invocations of the same command will use the saved location, avoiding a path search.
2。当您的 shell 扫描目录寻找命令并找到其他命令时
同样,由于上述文档,我们知道这一点:
There is an extra optimisation in the option
HASH_ALL
, also set by default: when the shell scans a directory to find a command, it will add all the other commands in that directory to the hash table.
好的,这就是所有的上下文。
回到问题,为什么?
为什么您要查找的命令没有出现在 $commands
数组中?为什么它们不在命令哈希中 table?
好吧,我们现在知道命令哈希 table 何时更新,因此我们可以推测不满足更新条件以及您可能处于何种情况的一些可能性:
- 第一次找到命令时
- 您最近安装了一个新命令,但从未 运行 安装它。
- 您已经移动了一个现有命令,但从未运行它。
- 当您的 shell 扫描目录以查找命令并找到其他命令时
- 您没有 运行 需要路径搜索的命令,该路径搜索会遍历安装您的 new/moved 命令的位置。
有什么可以做的吗?
这取决于你在做什么。
关键我知道命令的存在
不要使用 $commands
。使用 command -v <command_name>
,请参阅此 answer。
我只想在命令哈希中查看命令 table
您可以强制命令哈希 table 使用 hash -r
或在 ZSH rehash
.