我多次看到控制台命令,例如
./redis-server
Run Code Online (Sandbox Code Playgroud)
或者
./mongo
Run Code Online (Sandbox Code Playgroud)
./究竟是什么意思?
Ign*_*ams 10
.
是当前目录。所以该命令告诉 shell 在当前目录中查找可执行文件。
不要与 混淆. foo
,这是一个完全不同的命令。
Sky*_*eam 10
如果你运行一个没有任何前缀的命令,那么 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
Run Code Online (Sandbox Code Playgroud)
等同于
`pwd`/command
Run Code Online (Sandbox Code Playgroud)
或(在 BASH 上)
${PWD}/command
Run Code Online (Sandbox Code Playgroud)
正如在 Windows 命令行中已经提到的,command
如果您想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 $*
Run Code Online (Sandbox Code Playgroud)
然后使其可执行。
然后我打电话给我的系统管理员,告诉他一些关于我主目录中一些非常奇怪的文件名的故事。管理员很可能登录 shell(希望以 root 身份)cd 进入我的目录并执行 ls
. 会发生的情况是,/bin/ls
系统管理员将执行我的ls
脚本,该脚本只是将 的副本/etc/shadow
放入我的主文件夹中。好吧,管理员可能想知道为什么这ls
不会列出文件名。所以脚本只是/bin/ls
在最后一行执行“真实”命令。
因此,为了防止此类问题,大多数现代 Unix 系统都不会.
在搜索路径中包含当前目录 ( )。基本上,如果在没有指定完整路径的情况下执行命令,shell 将只在路径中执行二进制文件,该路径通常仅包含可信路径(非用户可写)。当您./mongo
在文档中看到时,这仅意味着您必须确保mongo
从正确的文件夹中执行,而不是mongo
路径中某处的某些二进制文件。
如果您经常从当前路径执行二进制文件,您可以简单地添加“.”。手动到 PATH 列表:
export PATH=".:$PATH"
Run Code Online (Sandbox Code Playgroud)
从现在开始,shell 将始终首先在当前目录中查找二进制文件。如上所述,这是非常危险的,因为您每次执行命令时都必须检查当前工作目录中的二进制文件 - 甚至在执行之前。不幸的是,要检查当前目录中的二进制文件,通常您会使用“ls”,它可能已经执行了您不期望的二进制文件。
我个人经常在我的$HOME/.profile
:
export PATH="~/bin:$PATH"
Run Code Online (Sandbox Code Playgroud)
这允许我将一些脚本放在我的$HOME/bin
文件夹中并运行它们而无需指定完整路径。但请记住,这$HOME/bin
对我来说也是一条值得信赖的道路。
另一个小笔记。每个目录(甚至是空目录)都包含两个硬链接。检查ls -a
输出:
.
..
Run Code Online (Sandbox Code Playgroud)
该.
条目指的是当前目录,而该..
条目硬链接到父目录。这是启用相对路径。当然,它也允许递归定义,如././././././command
执行command
的.
始终是指相同的目录。您还可以执行/bin/../bin/./././../bin/ls
完全有效的类似操作。
我希望这能澄清一下.
和..
条目的含义。