Eu posso cat /dev, posso ls /dev, não posso less /dev. Por catque me permite catesse diretório, mas não outros diretórios?
Eu posso cat /dev, posso ls /dev, não posso less /dev. Por catque me permite catesse diretório, mas não outros diretórios?
Respostas:
Historicamente (até V7 UNIX ou por volta de 1979), a readchamada do sistema funcionava em arquivos e diretórios. readem um diretório retornaria uma estrutura de dados simples que um programa do usuário analisaria para obter as entradas do diretório. De fato, a lsferramenta V7 fez exatamente isso - readem um diretório, analise a estrutura de dados resultante e produza em um formato de lista estruturada.
À medida que os sistemas de arquivos ficaram mais complexos, essa estrutura de dados "simples" ficou mais complicada, a ponto de uma readdirfunção de biblioteca ser adicionada para ajudar os programas a analisar a saída de read(directory). Sistemas e sistemas de arquivos diferentes podem ter diferentes formatos no disco, o que estava ficando complicado.
Quando a Sun apresentou o NFS (Network File System), eles queriam abstrair completamente a estrutura de diretórios em disco. Em vez de fazer do read(directory)retorno uma representação independente da plataforma do diretório, eles adicionaram uma nova chamada do sistema - getdirents- e foram banidos readem diretórios montados na rede. Essa chamada do sistema foi rapidamente adaptada para funcionar em todos os diretórios em vários tipos de UNIX, tornando-o o caminho padrão para obter o conteúdo dos diretórios. (Histórico abstraído de https://utcc.utoronto.ca/~cks/space/blog/unix/ReaddirHistory )
Como readdiragora é a maneira padrão de ler diretórios, read(directory)geralmente não é implementado (retornando -EISDIR) na maioria dos sistemas operacionais modernos (QNX, por exemplo, é uma exceção notável que é implementada readdircomo read(directory)). No entanto, com o design do "sistema de arquivos virtual" na maioria dos kernels modernos, na verdade cabe ao sistema de arquivos individual se a leitura de um diretório funciona ou não.
E, de fato, no macOS, o devfssistema de arquivos subjacente ao /devponto de montagem realmente suporta a leitura ( https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/miscfs/devfs/devfs_vnops.c#L629 ) :
static int
devfs_read(struct vnop_read_args *ap)
{
devnode_t * dn_p = VTODN(ap->a_vp);
switch (ap->a_vp->v_type) {
case VDIR: {
dn_p->dn_access = 1;
return VNOP_READDIR(ap->a_vp, ap->a_uio, 0, NULL, NULL, ap->a_context);
Isso chama explicitamente READDIRse você tentar ler /dev(a leitura de arquivos sob /devé tratada por uma função separada - devfsspec_read). Portanto, se um programa chamar a chamada do readsistema /dev, terá êxito e obterá uma lista de diretórios!
Este é efetivamente um recurso que permanece sob os primórdios do UNIX e que não é abordado há muito tempo. Parte de mim suspeita que isso esteja sendo mantido por algum motivo de compatibilidade com versões anteriores, mas poderia ser tão facilmente o fato de que ninguém se importa o suficiente para remover o recurso, pois não está prejudicando nada.
Menos é um visualizador de arquivos de texto, cat é uma ferramenta para copiar dados arbitrários. Portanto, menos realiza sua própria verificação para garantir que você não esteja abrindo algo que terá grandes quantidades de dados ou se comportará de maneira muito estranha. Por outro lado, o gato não tem tal verificação - se o kernel permite abrir algo (mesmo que seja um tubo ou um dispositivo ou algo pior), o gato irá lê-lo.
Então, por que o sistema operacional permite que o gato abra diretórios? Tradicionalmente, em sistemas no estilo BSD, todos os diretórios podiam ser lidos como arquivos, e era assim que os programas listavam um diretório em primeiro lugar: apenas interpretando as estruturas dirent armazenadas no disco.
Posteriormente, essas estruturas em disco começaram a divergir da diretiva usada pelo kernel: onde anteriormente um diretório era uma lista linear, os sistemas de arquivos posteriores começaram a usar hashtables, árvores B e assim por diante. Portanto, ler diretórios diretamente não era mais simples - o kernel desenvolveu funções dedicadas para isso. (Não tenho certeza se esse foi o motivo principal ou se foram adicionados principalmente por outros motivos, como cache.)
Alguns sistemas BSD continuam permitindo abrir todos os diretórios para leitura; Não sei se eles fornecem os dados brutos do disco, ou se eles retornam uma lista de diretórios emulados ou se permitem que o driver do sistema de arquivos decida.
Portanto, talvez o macOS seja um desses sistemas operacionais em que o kernel permite, desde que o sistema de arquivos forneça os dados. E a diferença é que /devestá em um devfssistema de arquivos que foi escrito para permitir isso nos primeiros dias, enquanto /em um sistema de arquivos APFS que omitiu esse recurso por ser desnecessário nos tempos modernos.
Disclaimer: Na verdade, eu não fiz nenhuma pesquisa sobre BSDs ou macOS. Eu estou apenas voando.
/etcsim, então usei isso como minha referência.
mountou /sbin/mountpara ver o que está montado no momento.
/devé um sistema de arquivos virtual usando o devfsdriver, enquanto /etcfaz parte do /sistema de arquivos usando o apfsdriver. Portanto, a razão catvai ler um e não o outro é a diferença entre o apfse devfsmotoristas.
neofetchpara sua informação :) i.imgur.com/3azpnDt.png