为什么在 sh 中输入“./”会产生“权限被拒绝”?

为什么在 sh 中输入“./”会产生“权限被拒绝”?

非常巧的是,我./今天在运行 ARM linux 的 sh shell 中输入,它产生了“权限被拒绝”错误,而不是通常的错误“是一个目录”。

sh 中的 ARM Linux:

[root@zynq DEBUG]# ./
-sh: ./: Permission denied
[root@zynq DEBUG]# uname -a
Linux zynq 3.8.0-xilinx #1 SMP PREEMPT Mon May 19 13:01:00 PDT 2014 armv7l GNU/Linux
[root@zynq DEBUG]# echo $SHELL
/bin/sh

bash 中的 Debian Jessie:

root@hotbox:~# ./
bash: ./: Is a directory
root@hotbox:~# uname -a
Linux hotbox 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt9-3~deb8u1 (2015-04-24) x86_64 GNU/Linux
root@hotbox:~# echo $SHELL
/bin/bash

我知道我正在尝试执行一个目录,但我很好奇:为什么 sh 会产生权限错误?

答案1

如果我猜的话,您sh更喜欢简单性或性能而不是用户友好性。 “权限被拒绝”错误是由perror(3),用于打印错误消息的标准函数。例如:

$ cat foo.c       
#include <stdio.h>
#include <unistd.h>

int main()
{
    char* const args[] = { "/usr", NULL };
    if (execv(args[0], args))
        perror(args[0]);

    return 0;
}
$ gcc -o foo foo.c
$ ./foo
/usr: Permission denied

bash可能会检查路径是否是目录。当然,这会稍微慢一些,并且代码也会稍微长一些。

bashzsh等有不止一个理由进行检查 - 它们允许您“运行”到目录的路径cd

$ shopt -s autocd
$ cd /
$ pwd
/
$ /usr/share
cd /usr/share
$ pwd
/usr/share

dash就(Debian/bin/sh指出的)而言/bin/dash,情况几乎就是这样。执行命令的代码位于shellexec():

if (strchr(argv[0], '/') != NULL) {
    tryexec(argv[0], argv, envp);
    e = errno;
} else {
// snip
exerror(EXEXIT, "%s: %s", argv[0], errmsg(e, E_EXEC));

该函数调用errms():

const char *
errmsg(int e, int action)
{
    if (e != ENOENT && e != ENOTDIR)
        return strerror(e);

    if (action & E_OPEN)
        return "No such file";
    else if (action & E_CREAT)
        return "Directory nonexistent";
    else
        return "not found";
}

strerror(3)是另一个标准函数,例如perror.strerror返回错误信息,perror直接打印。

相关内容