Shell 为什么*nix命令行通过相对于当前目录的路径启用执行?
很长一段时间以来,我一直认为*NIX shell不支持通过相对于当前目录的路径运行可执行文件。还有一些帖子解释了为什么在path中使用工作目录是一种不好的做法。不过,很容易看出以下示例是有效的:Shell 为什么*nix命令行通过相对于当前目录的路径启用执行?,shell,unix,Shell,Unix,很长一段时间以来,我一直认为*NIX shell不支持通过相对于当前目录的路径运行可执行文件。还有一些帖子解释了为什么在path中使用工作目录是一种不好的做法。不过,很容易看出以下示例是有效的: % cat<<EOF > temp/a ? #!/bin/sh ? echo "Hello looser!" ? EOF % chmod 750 temp/a % temp/a Hello looser! %cat您始终可以通过指定程序的相对路径来执行程序。没有要求您必须使用绝对路径
% cat<<EOF > temp/a
? #!/bin/sh
? echo "Hello looser!"
? EOF
% chmod 750 temp/a
% temp/a
Hello looser!
%cat您始终可以通过指定程序的相对路径来执行程序。没有要求您必须使用绝对路径。实际上,您执行程序的方式非常常见。这与执行无关。这是因为您可以使用绝对或相对名称命名文件,而可执行文件只是普通文件
为什么它很危险?(路径中的
)
考虑一个调用命令的脚本,如catfoo
,如果路径中有
,则可以在将代替原始目录执行的同一目录中创建命令cat
。如果在没有/
的情况下编写命令
,则shell将搜索该命令的$path
如果使用相对目录编写dir/command
,则会出现/
,shell不会搜索$PATH
。它相对于当前目录对其进行解释dir/command
始终解析为/dir/command
将
放在$PATH
中是危险的,因为您可能键入命令
打算运行/usr/bin/command
,但如果它存在于当前目录中,则实际会得到/command
。事实上,危险的不仅仅是
:任何相对路径都是危险的$PATH
应该只包含绝对路径。
因此,您的意思是相对路径应隐式地以当前目录作为前缀,当相对路径为空时,例外情况应视为在$path
中搜索的方向
是的,你可以这么说。但我更喜欢重新定义它。更好的方法是理解shell在做什么,而不是内核在做什么
解释相对路径由内核隐式处理。当shell执行类似于执行程序的系统调用时,内核知道父进程的当前目录,并相对于它解析dir/command
。shell不必首先将路径转换为绝对路径。内核可以处理绝对路径和相对路径
不过,内核对$PATH
一无所知。这是一个shell构造。请记住,shell是一个更高级别的软件。shell决定,如果您键入一个简单的命令名,但其中没有/
,它不会简单地将该命令传递给内核。如果有,键入cat
将只执行/cat
。没有人希望这样
相反,shell认为缺少/
意味着它将在$PATH
中搜索命令。它将搜索/bin
,/usr/bin
,$HOME/bin
,等等。如果您在$PATH
中列出了
,它还会搜索当前目录,但不要这样做!您不希望它运行/cat
。没有,先生
如果shell在$PATH
中找到一个可执行文件,那么它会将其转换为绝对路径名并将其传递给内核。内核看到execve(“/usr/bin/cat”,…)
如果是这样的话,并且您从一些正式规范中知道,我将非常感谢您的参考。我确实需要确切地知道
见:
如果命令名不包含斜杠,shell将尝试定位它
如果名称…不包含斜杠,bash将在路径的每个元素中搜索包含该名称的可执行文件的目录
如果搜索成功,或者如果命令名包含一个或多个斜杠,则shell将执行命名程序
当然不总是-除非目录位于路径中,否则不能在当前目录中运行exe
@v.v如果路径中没有该目录,则可以在当前目录中运行exe
,只需使用/exe
@MarkSetchell/
是带别名的完整路径。@v.v“带别名”?@v.v否。POSIX将绝对路径名定义为以单个/
开头的路径名。看,我知道为什么路径中的
是不好的做法。我想知道的是为什么temp/a
可以工作,而a
(在当前目录中)不能工作-当可以使用相对路径调用二进制时,是否有明确的策略?“无论何时但不在当前目录中”对我来说似乎很奇怪。您可能有一个“全局”脚本,它调用子目录中的下标,每个子目录在自己的目录中执行特定的任务。这很常见,是的,我可能:)但问题是不同的:通过相对路径调用可执行文件的确切规范是什么。不正确:如果当前目录中有可执行文件exe
,则不能将其称为exe
。如果键入exe
,则shell将根据我的第一段搜索$path
。只有当$PATH
包含
时,它才会搜索当前目录。这就是为什么它不应该!我在Bash手册中添加了一条引文。这一切都是关于斜杠的存在与否的/
。