Por que os componentes internos do Shell não podem ser executados com letras maiúsculas, mas outros comandos podem?

33

Por que é isso?

Quando eu faço isso

CD ~/Desktop

Não me leva para a área de trabalho. Mas isso:

echo "foo
bar" | GREP bar

me dá:

bar
Mostrar nome
fonte
4
Verifique se alias GREPou which GREPproduz alguma coisa.
chepner
1
Ai está. Você tem um comando chamado GREP, que é distinto de grep. (É verdade que pode ser apenas um hard link ou link simbólico para /usr/bin/grep, mas do ponto de vista da Shell, é um comando separado.)
chepner
12
Espere: você está no Mac OS X, não está? Por padrão, o HFS + preserva maiúsculas e minúsculas, o que significa que se o caso importa quando você cria um arquivo, mas uma vez que o arquivo existe, as pesquisas não diferenciam maiúsculas de minúsculas. Ou seja, bashpode solicitar um arquivo chamado GREP, mas o sistema de arquivos considera grepuma correspondência.
chepner
1
Sim, porque é Unix.
DisplayName 30/10
4
Os sistemas de arquivos são independentes do sistema operacional. Você pode usar outros sistemas de arquivos com o Mac OS X e (em teoria) usar o HFS + com outros sistemas operacionais. Além disso, você pode fazer o HFS + diferencia maiúsculas de minúsculas; o comportamento de preservação de caso é apenas o padrão por razões históricas.
Chepner # 30/14

Respostas:

71

Das suas outras perguntas, suponho que você esteja usando o OS X. O sistema de arquivos HFS + padrão no OS X não diferencia maiúsculas de minúsculas: você não pode ter dois arquivos chamados "abc" e "ABC" no mesmo diretório e tentando acessar qualquer nome chegará ao mesmo arquivo. O mesmo pode acontecer no Cygwin ou em sistemas de arquivos que não diferenciam maiúsculas de minúsculas (como FAT32 ou ciopfs ) em qualquer lugar.

Por grepser um executável real, ele foi procurado no sistema de arquivos (nos diretórios de PATH). Quando o seu shell procurar /usr/binpor um grepou GREPencontrará o grepexecutável.

Os componentes internos do shell não são pesquisados ​​no sistema de arquivos: como são integrados, eles são acessados ​​através de comparações de strings (com distinção entre maiúsculas e minúsculas) dentro do próprio shell.

O que você está encontrando é um caso interessante. Enquanto cdé um builtin, acessado com distinção entre maiúsculas e minúsculas, CDé encontrado como um executável /usr/bin/cd. O cdexecutável é bastante inútil: porque cdafeta o ambiente atual de execução do shell, ele sempre é fornecido como um shell regular , mas existe um cdexecutável para o bem do POSIX , que altera o diretório por si mesmo e termina imediatamente, deixando o shell ao redor onde começou.

Você pode experimentá-los com o typebuiltin :

$ type cd
cd is a shell builtin
$ type CD
CD is /usr/bin/CD

typeinforma o que o shell fará quando você executar esse comando. Quando você executa, cdvocê acessa o builtin, mas CDencontra o executável. Para outros buildins, o builtin e o executável serão razoavelmente compatíveis (try echo), mas, para cdisso, não é possível.

Michael Homer
fonte
1
boa resposta. Eu estava prestes a dizer cygwin, que teria o mesmo efeito.
27413 Joshua
@ Josué O problema do OP está resolvido, mas acho que para outros leitores da pergunta, uma resposta baseada no cygwin seria pelo menos tão útil quanto a existente; Talvez você possa fazer disso uma resposta separada, mesmo que curta, e adiando a existente para obter detalhes?
Volker Siegel
1
Por que o posix exigiria um comando inútil como o cd, e por que o cd interno do osx não se qualifica?
John #
2
51 votos positivos! Eu deveria ter acabado de postar uma resposta, em vez de um comentário :)
chepner
1
/ usr / bin / cd tem um propósito. a sintaxe é / usr / bin / cd argumentos do programa diretório
Joshua