Qual é a diferença entre um comando embutido e um que não é?

72

Existe alguma diferença intrínseca entre um comando interno e outro comando que nominalmente pode fazer a mesma coisa?

por exemplo. Os integrados recebem tratamento "especial"? ... há menos sobrecarga executando-os? .. ou eles são simplesmente 'embutidos'; como o painel do seu carro?

... e há uma lista definitiva (atual) desses componentes?

Peter.O
fonte

Respostas:

90

Nos seus comentários, você parece estar confuso sobre exatamente o que é um shell . O kernel é responsável por gerenciar o sistema. É a parte que realmente carrega e executa programas, acessa arquivos, aloca memória, etc. Mas o kernel não possui interface com o usuário; você só pode se comunicar com ele usando outro programa como intermediário.

Um shell é um programa que imprime um prompt, lê uma linha de entrada sua e depois a interpreta como um ou mais comandos para manipular arquivos ou executar outros programas. Antes da invenção da GUI, o shell era a principal interface do usuário de um sistema operacional. No MS-DOS, o shell foi chamado command.come poucas pessoas tentaram usar outro. No Unix, no entanto, há muito tempo que vários usuários podem escolher.

Eles podem ser divididos em 3 tipos. Os shells compatíveis com Bourne usam a sintaxe derivada do shell Bourne original . Os shells C usam a sintaxe do shell C original . Depois, existem shells não tradicionais que inventam sua própria sintaxe ou emprestam uma de alguma linguagem de programação e geralmente são muito menos populares que os dois primeiros tipos.

Um comando interno é simplesmente um comando que o shell executa sozinho, em vez de interpretá-lo como uma solicitação para carregar e executar outro programa. Isso tem dois efeitos principais. Primeiro, geralmente é mais rápido, porque carregar e executar um programa leva tempo. Obviamente, quanto mais tempo o comando leva para executar, menos significativo é o tempo de carregamento comparado ao tempo geral de execução (porque o tempo de carregamento é razoavelmente constante).

Em segundo lugar, um comando interno pode afetar o estado interno do shell. É por isso que comandos como cd devem ser integrados, porque um programa externo não pode alterar o diretório atual do shell. Outros comandos, como echo, podem ser integrados para eficiência, mas não há razão intrínseca para que eles não possam ser comandos externos.

Quais comandos estão embutidos dependem do shell que você está usando. Você terá que consultar sua documentação para obter uma lista (por exemplo, bashos comandos internos estão listados no Capítulo 4 deste manual ). O typecomando pode dizer se um comando está embutido (se o seu shell for compatível com POSIX), porque o POSIX exige que typeseja embutido. Se whichnão estiver embutido no seu shell, provavelmente não saberá sobre os embutidos do seu shell, mas apenas procurará programas externos.

cjm
fonte
Os aplicativos se comunicam com o kernel emitindo interrupções, na verdade.
Nathan Osman
11
@ George: Os aplicativos se comunicam com o kernel emitindo syscalls, que dependendo do sistema operacional e da arquitetura podem ou não usar interrupções. Usuários, como regra, não emitem interrupções.
Gilles 'SO- stop be evil'
2
@cjm: Parece tão simples quando você explica assim:) ... você certamente ajudou a limpar o nevoeiro ... apenas uma bruma agora ... (na verdade, é exatamente assim que o tempo está aqui, nesta manhã. .. agradavelmente enevoadas;) ... obrigado
Peter.O
@Gilles: Sério? Eu pensei que todos os programas em modo de usuário se comunicavam com o kernel através de interrupções (em certas arquiteturas, é claro).
21411 Nathan Osman
2
@ cjm Resposta muito completa e instrutiva. Eu aprendi muito lendo isso. :)
ankush981
37

Existem três níveis de utilitários embutidos:

  • Alguns utilitários são realmente parte do shell como uma linguagem de programação, mesmo que não sejam palavras reservadas . Eles são utilitários de controle de fluxo ( ., :, break, continue, return, trap, exit, exec, eval), utilitários de parâmetros relacionados com o ( set, unset, shift, export, readonly, local¹, typeset¹), utilitários de alias ( aliasm², unalias²) e times³. Esses embutidos especiais recebem tratamento especial:

    • Se você passar os argumentos errados para um built-in especial, o próprio shell pode abortar, em vez de simplesmente pular para o próximo comando depois de exibir uma mensagem de erro.
    • A sintaxe de pré-atribuição foo=bar utilitytem um significado diferente: é uma atribuição de parâmetro comum (ou seja, equivalente a foo=bar; utility), em vez de atribuir ao ambiente apenas pela duração do utilitário.
  • Alguns utilitários precisam ser implementados dentro do shell porque eles agem nas configurações internas do shell. Isso inclui:

    • utilitários que atuam sobre diretório atual do shell, como cd, dirs, pushd, popd;
    • utilitários de controle de emprego, tais como bg, disown, fg, jobs, wait;
    • utilitários que ler ou manipular outros atributos de casca, tais como builtin, command, hash, read, type, ulimit, umask;
    • utilidades relacionadas com recursos interativos, quando eles estão presentes, tais como fc, history, bind.
  • Alguns utilitários são geralmente implementadas como built-ins puramente para o desempenho : echo, printf, test, true, false.

Os shells avançados, como bash , ksh e zsh, geralmente têm mais recursos internos, geralmente para implementar recursos não padrão (geralmente para interação). O manual de cada shell informará quais comandos estão embutidos, embora alguns shells ( zsh , pelo menos) suportem módulos carregáveis ​​dinamicamente que podem fornecer mais embutidos.

¹ Desconhecido para POSIX, mas especial no ksh e em vários outros shells.
² Comum no POSIX, mas especial no ksh e em várias outras conchas.
³ In ksh, timesé um invólucro em torno da timepalavra-chave: é um alias para { { time;} 2>&1;}. Observe que o POSIX permite timeser um utilitário externo com análise comum ou uma palavra-chave que se aplica a todo um pipeline (que está em ksh, bash em zsh).

Gilles 'SO- parar de ser mau'
fonte
3
Essas distinções são realmente importantes.
dmckee
Pergunta rápida, então o que significa "atribuição de parâmetro comum" quando fazemos while IFS= read -r line?
Sergiy Kolodyazhnyy
O @SergiyKolodyazhnyy readnão é um componente especial, portanto, IFS=readdefine a variável apenas pela duração do comando.
Gilles 'SO- stop be evil'
10

Um builtin é um comando fornecido pelo shell, e não por um programa externo. Aqui estão as listas bashdos buildins (eles também estão listados na página do manual do bash) e zshdos buildins . kshfornece uma lista executando builtin.

Para saber se um comando específico é interno, você pode executar type command. Tente type fore type lsveja isso.

Shawn J. Goff
fonte
typeparece fazer o truque; obrigado por isso ... mas ainda me pergunto o que "fornecido pelo shell" significa ... Talvez eu precise entender melhor como o shell se relaciona com o kernel .... mas não às 2 da manhã .. Eu irei Voltar para este amanhã
Peter.O
1

Cada distro e shell possui uma coleção diferente de comandos versus funções internas do shell. Geralmente, a ideia é que os shells incorporem as funções mais comuns e simples para economizar tempo, velocidade e integrar a vontade com o restante do conjunto de recursos. A sobrecarga é muito menor, pois não precisa iniciar outro processo do sistema. No entanto, é possível misturar e combinar. Você pode executar um shell que possui um buildin para alguma coisa, mas também possui esse comando no seu sistema. Normalmente, o built-in teria prioridade, mas você poderia controlar isso.

Você pode descobrir facilmente se um comando específico é incorporado ou não executando type mycommand. A maioria das páginas de manual do shell também possui uma lista de seus componentes internos.

Editar: use typepara descobrir se um comando é interno e, se não, whichpara saber de onde será executado.

Caleb
fonte
@ Caleb: obrigado pelo seu comentário, mas isso me deixa pensando sobre o que exatamente é um "processo do sistema". Continuo vendo referências até então, mas não entendo onde está a distinção .... (btw não posso veja como 'qual' é um indicador absoluto) ... por exemplo, 'qual =>"/bin/echo" and tipo de eco echo =>"echo is a shell builtin", but 'which dd=> "/ bin / dd" e type dd=> "dd é / bin / dd" ... então, estou meio lá ....
Peter.O
"System procses" significa apenas que está sendo iniciado como um aplicativo independente gerenciado pelo kernel. A alternativa no caso de builtins é apenas executar uma subfunção no código já em execução do seu shell. No exemplo que você dá, typeé o melhor indicador do que está sendo executado, mas você percebe que echoambos são internos e há um aplicativo com esse nome. Se o seu shell não tivesse um sistema interno, ele seria executado.
Calebe
2
whichnão é necessariamente um comando interno e, se não for, ele não saberá sobre os recursos internos do shell. O POSIX exige que typeseja um comando interno, para que ele sempre saiba sobre os internos.
Cjm
Muitos sistemas são fornecidos com um apelido para whicha typeou algum conjunto de opções por exemplo alias which='type -path'- esta poderia ser a fonte de confusão.
Random832
11
Não posso aprovar isso até que whichseja substituído por type. Eu usei o que, uma e outra vez, sem saber typee fiquei muito surpreso em saber , isso whiché certo, se decidir entre os programas.
usuário desconhecido