非常巧的是,我./
今天在运行 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
可能会检查路径是否是目录。当然,这会稍微慢一些,并且代码也会稍微长一些。
bash
、zsh
等有不止一个理由进行检查 - 它们允许您“运行”到目录的路径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
直接打印。