Por que o teste -e falha em um arquivo em um diretório com apenas permissões de leitura?

2

Pelo que eu entendi sobre a permissão de leitura em diretórios, ele permite listar quais arquivos estão em um diretório e é sobre isso.

Dado um diretório com permissões 0744, de propriedade de userA :

[userA@localhost ~]$ mkdir -m 0744 /tmp/semi-secret
[userA@localhost ~]$ ls -ld /tmp/semi-secret/
drwxr--r--. 2 userA userA 6 Aug 29 10:15 /tmp/semi-secret/
[userA@localhost tmp]$ touch semi-secret/foobar.txt
[userA@localhost tmp]$ chmod 0600 semi-secret/foobar.txt

Para userB , a existência do arquivo foobar.txt é aparente no comando ls .

[userB@localhost ~]$ ls -l /tmp/semi-secret/
ls: cannot access /tmp/semi-secret/foobar.txt: Permission denied
total 0
-????????? ? ? ? ?            ? foobar.txt

Mas por que o comando test -e sai com um status diferente de zero? Seu único trabalho é confirmar se um arquivo existe ou não, e as permissões de diretório devem permitir isso.

[userB@localhost ~]$ test -e /tmp/semi-secret/foobar.txt || echo "The file doesn't exist."
The file doesn't exist.
    
por Steve 29.08.2018 / 17:31

2 respostas

4

Como até mesmo a chamada do sistema stat(2) não funciona para nenhum arquivo em um diretório que não tenha ox bit nas permissões, tudo o que for baseado na chamada do sistema stat(2) falhará nesse diretório.

Se o diretório tiver o r bit definido, você poderá realmente ler o conteúdo desse diretório usando readdir() , mas não poderá stat ou open nenhum arquivo.

Ao contrário, um diretório que tenha o x bit definido, permite a você stat(2) ou open arquivos se você souber os nomes de arquivos relacionados, mas não pode usar readdir() para recuperar o conteúdo do diretório relacionado .

test -e sai com um status diferente de zero, caso o arquivo não exista (após a resolução do symlink, de modo que também se aplica aos links simbólicos existentes para não existente ou arquivos não acessíveis) ou qualquer erro ocorre ao tentar stat(2) o arquivo relacionado.

    
por 29.08.2018 / 17:34
3

Para complementar a resposta do @shily, uma maneira de verificar se um determinado diretório para o qual você acessou, mas não necessariamente o acesso pesquisa , contém uma entrada de um determinado nome, é ler o conteúdo de esse diretório e procure por esse nome de arquivo.

Você pode usar o globo ocular para isso.

set -- /tmp/semi-secret/[f]oobar.txt
if [ "$1" = /tmp/semi-secret/foobar.txt ]; then
  echo exists
fi

Com zsh , você também pode fazer:

if ()(($#)) /tmp/semi-secret/foobar.txt(N); then
  echo exists
fi

Com find implementações que suportam -maxdepth :

if find /tmp/semi-secret -mindepth 1 -maxdepth 1 -name foobar.txt -print |
     grep -q '^'; then
  echo exists
fi

Exceto pela solução zsh , é difícil adaptar-se a nomes de arquivos arbitrários.

    
por 29.08.2018 / 17:52