Если бы я мог предположить, ваш sh
предпочитает простоту или производительность удобству пользователя. Ошибка "permission denied" - это ошибка, предоставляемая perror(3)
, стандартной функцией для печати сообщения об ошибке. Например:
$ cat foo.c
#include
#include
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
печатает его напрямую.
Я открыл тикет, и разработчики обнаружили, что это ошибка.
Они работают над этим.
https://bitbucket.org/tildeslash/monit/issues/769/monit-status-doesnt-work