我多次看到过类似的控制台命令
./redis-server
或者
./mongo
到底是什么./方法?
答案1
.
是当前目录。因此该命令告诉 shell 在当前目录中查找可执行文件。
不要与 混淆. foo
,这是一个完全不同的命令。
答案2
当您运行不带任何前缀的命令时,Unix 系统会在 中查找该命令PATH
。例如,如果您输入ls
,Unix 将遍历 中列出的所有路径PATH
以查找ls
二进制文件。
例如,假设您的PATH
设置为,/bin:/usr/bin:/usr/local/bin
那么只需输入ls
就会让您的 shell 找到命令/bin/ls
并执行它。
Unix 系统将按照路径列出的顺序评估路径PATH
。因此,如果您ls
安装了多个路径,它将执行最先找到的路径,而忽略其他路径。因此,在上面的例子中,如果您只键入,则可能ls
安装了另一个/usr/local/bin/ls
从未使用过的路径ls
。如果您想执行/usr/local/bin/ls
,那么您可以修改PATH
或使用绝对路径键入/usr/local/bin/ls
。
现在到了./
前缀。.
只是引用当前文件夹。 因此,如果您在命令前加上前缀,./
shell 会在当前文件夹中查找该命令。 事实上
./command
等同于
`pwd`/command
或(在 BASH 上)
${PWD}/command
command
正如前面提到的,如果要从当前文件夹执行,您可能习惯于在 Windows 命令行上直接输入command.exe
。这是因为 Windows 在搜索路径之前会先在当前工作文件夹中隐式查找二进制文件。
不幸的是,这非常不安全。假设我想窃取我作为普通用户无法访问的用户信息。我只需将一个非常简单的脚本放入我的主目录中,名为“ls”,内容如下:
#!/bin/bash
cp /etc/shadow /home/my-user > /dev/null 2>&1
chown my-user /home/my-user/shadow > /dev/null 2>&1
/bin/ls $*
然后使其可执行。
然后我打电话给系统管理员,告诉他我的主目录中一些非常奇怪的文件名。很可能管理员登录 shell(希望以 root 身份)进入我的目录并执行 ls
。将发生的是,/bin/ls
系统管理员将执行我的ls
脚本,而该脚本只会将副本/etc/shadow
放入我的主文件夹中。好吧,管理员可能会想知道为什么这ls
不会列出文件名。因此,脚本只执行/bin/ls
最后一行的“真实”命令。
因此,为了防止出现此类问题,大多数现代 Unix 系统都不将当前目录 ( .
) 包含在搜索路径中。基本上,如果执行命令时未指定完整路径,则 shell 将只执行路径中的二进制文件,这些路径通常仅包含受信任的路径(用户不可写)。当您./mongo
在文档中看到这时,这仅意味着您必须确保mongo
从正确的文件夹执行,而不是mongo
从路径中的某个二进制文件执行。
如果您经常从当前路径执行二进制文件,您可能只需手动将“。”添加到 PATH 列表中:
export PATH=".:$PATH"
从现在开始,shell 将始终首先在当前目录中查找二进制文件。如上所述,这非常危险,因为每次执行命令时,您都必须检查当前工作目录中的二进制文件 - 甚至在执行命令之前。不幸的是,要检查当前目录中的二进制文件,您通常会使用“ls”,但这可能已经执行了您意想不到的二进制文件。
我个人经常在我的中使用以下内容$HOME/.profile
:
export PATH="~/bin:$PATH"
这样我就可以将一些脚本放入我的$HOME/bin
文件夹中并运行它们,而无需指定完整路径。但请记住,这$HOME/bin
对我来说也是一条受信任的路径。
另一个小提示。每个目录(即使是空目录)都包含两个硬链接。检查ls -a
输出:
.
..
条目.
引用当前目录,而..
条目硬链接到父目录。这是启用相对路径。当然,它还允许递归定义,例如././././././command
执行为command
始终.
引用同一目录。您还可以执行类似这样的操作,/bin/../bin/./././../bin/ls
这是完全有效的。
我希望这能稍微解释一下.
和..
条目的含义。