¿Cuál es la diferencia entre un comando incorporado y uno que no lo es?

72

¿Hay alguna diferencia intrínseca entre un comando incorporado y otro comando que nominalmente puede hacer lo mismo?

p.ej. ¿Las construcciones reciben un tratamiento "especial"? ... ¿hay menos gastos generales ejecutándolos? .. o simplemente están "incorporados"; como el tablero de tu auto?

... ¿y hay una lista definitiva (actual) de estos componentes?

Peter.O
fuente

Respuestas:

90

Por sus comentarios, parece estar confundido acerca de qué es exactamente un shell . El kernel es responsable de administrar el sistema. Es la parte que realmente carga y ejecuta programas, accede a archivos, asigna memoria, etc. Pero el núcleo no tiene interfaz de usuario; solo puede comunicarse con él utilizando otro programa como intermediario.

Un shell es un programa que imprime un aviso, lee una línea de entrada de usted y luego lo interpreta como uno o más comandos para manipular archivos o ejecutar otros programas. Antes de la invención de la GUI, el shell era la interfaz de usuario principal de un sistema operativo. En MS-DOS, se llamó al shell command.comy pocas personas intentaron usar uno diferente. En Unix, sin embargo, durante mucho tiempo ha habido múltiples shells entre los que los usuarios pueden elegir.

Se pueden dividir en 3 tipos. Los shells compatibles con Bourne usan la sintaxis derivada del shell Bourne original . Los shells C usan la sintaxis del shell C original . Luego hay shells no tradicionales que inventan su propia sintaxis, o toman prestada una de algún lenguaje de programación, y generalmente son mucho menos populares que los dos primeros tipos.

Un comando incorporado es simplemente un comando que el shell ejecuta por sí mismo, en lugar de interpretarlo como una solicitud para cargar y ejecutar algún otro programa. Esto tiene dos efectos principales. Primero, generalmente es más rápido, porque cargar y ejecutar un programa lleva tiempo. Por supuesto, cuanto más tiempo tarda el comando en ejecutarse, menos significativo es el tiempo de carga en comparación con el tiempo de ejecución general (porque el tiempo de carga es bastante constante).

En segundo lugar, un comando incorporado puede afectar el estado interno del shell. Es por eso que los comandos como cd deben estar incorporados, porque un programa externo no puede cambiar el directorio actual del shell. Otros comandos, como echo, pueden estar integrados para la eficiencia, pero no hay ninguna razón intrínseca para que no puedan ser comandos externos.

Los comandos incorporados dependen del shell que esté utilizando. Tendrá que consultar su documentación para obtener una lista (por ejemplo, bashlos comandos integrados se enumeran en el Capítulo 4 de su manual ). El typecomando puede decirle si un comando está incorporado (si su shell es compatible con POSIX), porque POSIX requiere que typeesté incorporado. Si whichno está integrado en su shell, entonces probablemente no sabrá acerca de los complementos de su shell, pero solo buscará programas externos.

cjm
fuente
Las aplicaciones se comunican con el núcleo mediante la emisión de interrupciones, en realidad.
Nathan Osman
11
@George: las aplicaciones se comunican con el kernel emitiendo syscalls, que dependiendo del sistema operativo y la arquitectura pueden o no usar interrupciones. Los usuarios, por regla general, no emiten interrupciones.
Gilles 'SO- deja de ser malvado'
2
@cjm: Suena tan simple cuando lo explicas así:) ... ciertamente has ayudado a despejar la niebla ... solo una niebla ligera ahora ... (en realidad así es el clima aquí, esta mañana. .. agradablemente brumoso;) ... gracias
Peter.O
@Gilles: ¿En serio? Pensé que todos los programas en modo de usuario se comunicaban con el núcleo a través de interrupciones (en ciertas arquitecturas, por supuesto).
Nathan Osman
2
@cjm Respuesta muy exhaustiva e instructiva. Aprendí mucho leyéndolo. :)
ankush981
37

Hay tres niveles de utilidades incorporadas:

  • Algunas utilidades son realmente parte del shell como lenguaje de programación, a pesar de que no son palabras reservadas . Son utilidades de control de flujo ( ., :, break, continue, return, trap, exit, exec, eval), servicios públicos de parámetros relacionados ( set, unset, shift, export, readonly, local¹, typeset¹), alias utilidades ( alias², unalias²) y times³. Estas incorporaciones especiales reciben un tratamiento especial:

    • Si pasa los argumentos incorrectos a una función integrada especial, el shell en sí puede abortar, en lugar de saltar al siguiente comando después de mostrar un mensaje de error.
    • La sintaxis previa a la asignación foo=bar utilitytiene un significado diferente: es una asignación de parámetros ordinaria (es decir, equivalente a foo=bar; utility), en lugar de asignarla al entorno solo durante la duración de la utilidad.
  • Algunas utilidades deben implementarse dentro del shell porque actúan en la configuración interna del shell. Esto incluye:

    • utilidades que actúan sobre el directorio actual de la concha, tales como cd, dirs, pushd, popd;
    • utilidades de control de trabajo, tales como bg, disown, fg, jobs, wait;
    • utilidades que leen o manipulan otros atributos de la cáscara, tales como builtin, command, hash, read, type, ulimit, umask;
    • utilidades relacionadas con características interactivas, cuando están presentes, tales como fc, history, bind.
  • Algunas de las utilidades se implementan típicamente como muebles empotrados puramente para el rendimiento : echo, printf, test, true, false.

Los shells avanzados como bash , ksh y zsh suelen tener más funciones integradas, a menudo para implementar características no estándar (generalmente para la interacción). El manual de cada shell le dirá qué comandos están incorporados, aunque algunos shells ( zsh , al menos) admiten módulos cargables dinámicamente que pueden proporcionar más incorporaciones.

¹ Desconocido para POSIX, pero especial en ksh y varios otros shells.
² Ordinario en POSIX, pero especial en ksh y varios otros shells.
³ En ksh, timeses un contenedor alrededor de la timepalabra clave: es un alias para { { time;} 2>&1;}. Tenga en cuenta que POSIX permite timeser una utilidad externa con análisis ordinario o una palabra clave que se aplica a una tubería completa (que está en ksh, bash en zsh).

Gilles 'SO- deja de ser malvado'
fuente
3
Estas distinciones son las realmente importantes.
dmckee
Pregunta rápida, entonces, ¿qué significa "asignación de parámetros ordinarios" cuando lo hacemos while IFS= read -r line?
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy readno es un generador especial, por lo que IFS=readestablece la variable solo durante la duración del comando.
Gilles 'SO- deja de ser malvado'
10

Un builtin es un comando proporcionado por el shell, en lugar de un programa externo. Aquí están las listas de bashlos componentes incorporados (también se enumeran en la página del manual de bash) y zshlos componentes incorporados . kshproporciona una lista ejecutando builtin.

Para saber si un comando en particular está integrado, puede ejecutar type command. Intenta type fory type lsver esto.

Shawn J. Goff
fuente
typeParece funcionar; gracias por eso ... pero todavía me pregunto qué significa "proporcionado por el shell" ... Tal vez necesito entender mejor cómo se relaciona el shell con el kernel ... pero no a las 2 AM ... Vendré volvamos a esto mañana
Peter
1

Cada distribución y shell tiene una colección diferente de comandos frente a las funciones de shell incorporadas. En general, la idea es que los shells incorporen las funciones más comunes y simples para ahorrar tiempo, velocidad e integración con el resto de su conjunto de características. La sobrecarga es mucho menor ya que no tiene que iniciar otro proceso del sistema. Sin embargo, es posible mezclar y combinar. Puede ejecutar un shell que tiene un buildin para algo, pero también tiene ese comando en su sistema. Por lo general, la construcción tendría prioridad, pero podría controlar eso.

Puede averiguar fácilmente si un comando específico está integrado o no ejecutando type mycommand. La mayoría de las páginas man de shell también tienen una lista de sus componentes integrados.

Editar: se usa typepara averiguar si un comando está integrado y, si no, whichpara saber desde dónde se ejecutará.

Caleb
fuente
@Caleb: gracias por tu comentario, pero me deja preguntándome qué es exactamente un "proceso del sistema". Sigo viendo referencias a continuación, pero no entiendo dónde radica la distinción ... (por cierto, no puedo vea cómo 'which' es un indicador absoluto) ... p. ej. 'which echo =>"/bin/echo" and type echo =>"echo is a shell builtin", but 'which dd=> "/ bin / dd" y type dd=> "dd is / bin / dd" ... así que estoy a medio camino ....
Peter.O
"Procesos del sistema" solo significa que se está iniciando como una aplicación independiente administrada por el núcleo. La alternativa en el caso de los builtins es simplemente ejecutar una subfunción en el código que ya se está ejecutando en su shell. En el ejemplo que da, typees el mejor indicador de lo que se está ejecutando, pero se da cuenta de que echoestá integrado y hay una aplicación con ese nombre. Si su caparazón no tuviera un sistema integrado, se ejecutaría uno.
Caleb
2
whichno es necesariamente un comando incorporado, y si no lo es, no sabrá acerca de las funciones integradas del shell. POSIX requiere que typesea ​​un comando integrado, por lo que siempre sabe sobre las incorporaciones.
cjm
Muchos sistemas se envían con un alias de whicha typeo algún conjunto de opciones por ejemplo alias which='type -path'- esto podría ser la fuente de confusión.
Random832
1
No puedo votar esto hasta que whichsea ​​reemplazado por type. Usé lo que, una y otra vez, sin saber typey estaba muy sorprendido de aprender, eso whiches correcto, si decidía entre programas.
Usuario desconocido