Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 为什么*nix命令行通过相对于当前目录的路径启用执行?_Shell_Unix - Fatal编程技术网

Shell 为什么*nix命令行通过相对于当前目录的路径启用执行?

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您始终可以通过指定程序的相对路径来执行程序。没有要求您必须使用绝对路径

很长一段时间以来,我一直认为*NIX shell不支持通过相对于当前目录的路径运行可执行文件。还有一些帖子解释了为什么在path中使用工作目录是一种不好的做法。不过,很容易看出以下示例是有效的:

% 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手册中添加了一条引文。这一切都是关于斜杠的存在与否的
/