it-swarm-es.tech

¿Por qué echo es un comando integrado de Shell?

$ which echo
echo: Shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

¿Por qué echo no es una utilidad independiente como ls, ps, cat etc? ¿Por qué es específico de Shell? ¿Alguna buena razón?

35
Lazer

Hay dos clases de elementos integrados:

  1. Algunos comandos deben estar integrados en el propio programa Shell porque no pueden funcionar si son externos.

    cd es uno de ellos, ya que si fuera externo, solo podría cambiar su propio directorio; no podría afectar el directorio de trabajo actual del Shell. (Ver también: ¿Por qué cd no es un programa? )

  2. La otra clase de comandos está integrada en el Shell puramente por eficiencia.

    El dashpágina de manual tiene una sección sobre elementos integrados que menciona printf, echo y test como ejemplos de comandos en esta clase.

Los sistemas Unix siempre han incluido ejecutables separados para comandos en esa segunda clase. Estos ejecutables separados todavía están disponibles en todos los sistemas Unixy que he usado, aunque también están integrados en todos los Shell que probablemente uses. ( POSIX en realidad requiere que estos ejecutables estén presentes).

Creo que echo se incorporó al Shell en AT&T Unix System V Release 3.1. Lo baso en comparaciones de dos ediciones diferentes de manuales para AT & Ts sistemas Unix de la serie 3B1 . Alguien ha escaneado amablemente las ediciones de 1986 de estos manuales y póngalos en línea ; estos corresponden a la versión original de SVR3. Puede ver que echo no está en la lista de la página 523 de Manual del usuario de UNIX System V, Volumen II , donde lo esperaría si el comando estuviera integrado en el Shell. En mi copia impresa local de los manuales SVR3.1 de 1987, echo aparece en esta sección del manual.

Estoy bastante seguro de que esto no es una innovación de Berkeley CSRG que AT&T trajo a casa. 4.3BSD salió el mismo año que SVR3, 1986, pero si observa página de manual sh.1 de 4.3BSD , verá que echo no está en la lista de la sección "Comandos especiales" de comandos integrados. Si CSRG hizo esto, eso nos deja con ganas de una fuente documentada para probarlo.

En este punto, puede preguntarse si echo fue integrado en el Shell antes que SVR3.1 y que este hecho simplemente no documentado hasta entonces. El código fuente Unix de AT&T anterior a SVR3 más reciente disponible para mí está en PDP-11 System III tarball , donde encontrará el código fuente de Bourne Shell. No encontrará echo en la tabla de comandos incorporada, que está en /usr/src/cmd/sh/msg.c. Basado en las marcas de tiempo en ese archivo, eso prueba que echo ciertamente no estaba en el Shell en 1980.


Trivialidades

El mismo directorio también contiene un archivo llamado builtin.c que no contiene nada específico para esta pregunta, pero encontramos este comentario interesante:

/*      
    builtin commands are those that Bourne did not intend
    to be part of his Shell.
    Redirection of i/o, or rather the lack of it, is still a
    problem..
*/      
72
Warren Young

Hay una tercera razón para que algunos comandos estén integrados: se pueden usar cuando es imposible ejecutar comandos externos.

A veces, un sistema se estropea tanto que el comando ls no funciona. En algunos casos, un echo * seguirá funcionando.

Otro ejemplo (¡más importante!) Es kill: si un sistema se queda sin PID libres, no es posible ejecutar /bin/kill (porque necesita un PID :-), pero el kill incorporado funcionará.

Por cierto, which es un comando externo (al menos no es interno en bash), por lo que no puede enumerar los comandos internos. Por ejemplo:

$ which echo
/bin/echo
$ type -a echo
echo is a Shell builtin
echo is /bin/echo
19
bhm

De acuerdo con Bash Reference Manual , se trata de conveniencia.

Los shells también proporcionan un pequeño conjunto de comandos integrados (incorporados) que implementan una funcionalidad imposible o inconveniente de obtener mediante utilidades independientes. Por ejemplo, cd, break, continue y exec) no se pueden implementar fuera del Shell porque manipulan directamente el propio Shell. Los archivos internos history, getopts, kill o pwd, entre otros, podrían implementarse en utilidades separadas, pero son más convenientes de usar como comandos integrados. Todas las incorporaciones de Shell se describen en las secciones siguientes.

La Advanced Bash Scripting Guide tiene una explicación más detallada:

"Un builtin es un comando contenido dentro del conjunto de herramientas Bash, literalmente integrado. Esto es por razones de rendimiento: los internos se ejecutan más rápido que los comandos externos, que generalmente requieren bifurcación 1 un proceso separado - o porque un incorporado en particular necesita acceso directo al interior de Shell ".

También tenga en cuenta que echo existe como una utilidad independiente en algunos sistemas. Esto es lo que tengo en mi sistema Darwin (MacOSX 10.5.8 - Leopard)

$ uname -a
Darwin Host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-Apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo

echo también está disponible como incorporado, pero aparentemente mis scripts usan/bin/echo en mi Mac, y usan un Bash incorporado en la mayoría de mis sistemas Linux y FreeBSD. Pero eso no parece importar, porque los scripts aún funcionan bien en todas partes.

13
Stefan Lasiewski

Para complementar la respuesta de bhm, digamos /bin se eliminó accidentalmente de su PATH. Le gustaría poder echo $PATH para averiguarlo, ¿verdad?

6
Daniel Hershcovich

Aunque la mayoría de los shells incluyen un echo incorporado hoy en día, los GNU CoreUtils también incluyen una implementación independiente del mismo:

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

Parece que no tiene GNU Coreutils instalado (la mayoría de los sistemas operativos de servidor y escritorio basados ​​en Linux lo tienen instalado de forma predeterminada, pero Linux embebido u otro UNIX podría usar colecciones alternativas de utilidades de Shell en su lugar)) .

Por cierto: si miras Busybox , verás que ls, ps y cat también son comandos integrados allí (o en menos puede ser; se usa para sistemas embebidos y todo lo que no se necesita puede omitirse).

2
JanC

Esta es la verdadera razón por la que echo debería ser una función incorporada de Shell:

Suponga que tiene una contraseña en $PASSWORD. ¿Cómo se escribe en un archivo ./password? Naturalmente, la mayoría de los programadores escribirían:

echo "$PASSWORD" >./password

Sin embargo, si echo no fuera un Shell incorporado, la contraseña se filtraría a todos los usuarios a través de la información de ps.

Por supuesto, si quiere ser inteligente al respecto, puede encontrar una manera de almacenar una contraseña sin echo, quizás explotando alguna otra característica de Shell:

cat >./password <<EOF
${PASSWORD}
EOF

Sin embargo, tener echo incorporado es un cinturón de seguridad importante, ya que la forma más obvia de guardar una contraseña en un archivo también debería funcionar.

1
DepressedDaniel