Por que digitar “./” em sh produce “permission denied”?

0

Perfeitamente, eu digitei ./ em um sh shell rodando o ARM linux e ele produziu "permissão negada" como um erro, ao contrário de "É um diretório", que é o erro comum.

ARM Linux no sh:

[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

Debian Jessie no bash:

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

Eu entendo que estou tentando executar um diretório, mas estou curioso: Por que sh produz um erro de permissão?

    
por stanri 12.11.2015 / 18:50

1 resposta

7

Se eu fosse adivinhar, seu sh favorece a simplicidade ou o desempenho em relação à facilidade de uso. O erro "permissão negada" é fornecido por perror(3) , uma função padrão para imprimir uma mensagem de erro. Por exemplo:

$ 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 provavelmente faz uma verificação para ver se o caminho é um diretório. Isso, claro, será um pouco mais lento e um código um pouco mais longo.

bash , zsh , etc. têm mais de um motivo para fazer a verificação - eles permitem que você "execute" um caminho para um diretório para cd :

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

No caso de dash ( /bin/sh do Debian aponta para /bin/dash ), esse é o caso. O código que executa o comando está em 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));

Essa função chama 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) é outra função padrão, como perror . strerror retorna a mensagem de erro, perror imprime diretamente.

    
por 12.11.2015 / 19:06

Tags