とても偶然にも、./
今日ARM Linuxを実行しているshシェルを入力していましたが、一般的な「ディレクトリです」エラーの代わりに「許可拒否」エラーが発生しました。
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の提示:
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
確認する理由が2つ以上あります。これにより、ディレクトリパスを「実行」できます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
それを直接印刷します。