¿Por qué lsrequiere un proceso separado para su ejecución? Sé la razón por la cual los comandos como cdno se pueden ejecutar mediante un mecanismo de bifurcación, pero ¿hay algún daño si lsse ejecuta sin bifurcación?
¿Por qué lsrequiere un proceso separado para su ejecución? Sé la razón por la cual los comandos como cdno se pueden ejecutar mediante un mecanismo de bifurcación, pero ¿hay algún daño si lsse ejecuta sin bifurcación?
Respuestas:
La respuesta es más o menos que lses un ejecutable externo. Puede ver su ubicación ejecutando type -p ls.
¿Por qué no está lsintegrado en la carcasa, entonces? Bueno, ¿por qué debería ser? El trabajo de un shell no es abarcar todos los comandos disponibles, sino proporcionar un entorno capaz de ejecutarlos. Algunos proyectiles modernos tienen echo, printfy su tipo de construcción, que técnicamente no tienen que ser construidos, pero están hechos por razones de rendimiento cuando se ejecutan repetidamente (principalmente en bucles estrechos). Sin hacerlos incorporados, el shell tendría que bifurcarse y ejecutar un nuevo proceso para cada llamada, que podría ser extremadamente lento.
Por lo menos, ejecutar ls, un ejecutable externo, requiere ejecutar una de la familia de llamadas de sistema ejecutivas. Usted podría hacer esto sin que se bifurcan, pero sería reemplazar la corteza primaria que está utilizando. Puede ver lo que sucede en esa instancia haciendo lo siguiente:
exec ls; echo "this never gets printed"
Dado que la imagen de proceso de su shell se reemplaza, el shell actual ya no es accesible después de hacer esto. Para que el shell pueda continuar ejecutándose después de ejecutar ls, el comando tendría que estar integrado en el shell.
La bifurcación permite reemplazar un proceso que no es su shell principal, lo que significa que puede continuar ejecutando su shell después.
echo, printf, etc.
cdno es un ejecutable externo?
cdejecutable en los sistemas operativos compatibles con POSIX ( ver aquí ). Sin embargo, si desea realmente chdir () en el proceso actual, debe tenerlo integrado en el shell.
El Manual de referencia de Bash dice:
Los comandos incorporados son necesarios para implementar funcionalidades imposibles o inconvenientes de obtener con utilidades separadas.
Es decir, los shells están diseñados para incluir solo comandos integrados si:
El lscomando no se ajusta a ninguno de los requisitos anteriores.
Sin embargo , aquí no hay ninguna restricción de programación que impida que lsse implique como una función integrada, que se ejecuta en el mismo proceso que el intérprete de bash. Las razones de diseño para que los comandos no se impliquen como elementos integrados de shell son:
En cuanto a la primera razón: desea que el caparazón sea lo más independiente y flexible posible. No desea que el shell se atasque en lsun montaje NFS que "no responde y sigue intentando".
En cuanto a la segunda razón: en muchos casos, es posible que desee utilizar un shell para un sistema que utiliza Busybox u otro sistema de archivos que tenga una lsimplementación diferente . O incluso use la misma fuente de shell en sistemas operativos que tienen lsimplementaciones diferentes .
En cuanto a la tercera razón: para expresiones como find . -type d | xargs ls -ladsería difícil o imposible implementarlas lsen el mismo proceso que el intérprete de shell.
En cuanto a la cuarta razón: algunos lscomandos pueden tardar mucho tiempo en completarse. Es posible que desee que el shell continúe haciendo otra cosa mientras tanto.
Nota: Vea esta publicación útil de Warren Young en respuesta a una pregunta similar.
lsen un proceso externo. Podría hacerse, pero sería complicado.
bashsalida alias | grep ls. entradacat /etc/passwd | while read a; do echo "$a"; done
lsNo requiere un proceso separado. Muy pocos comandos requieren un proceso separado: solo los que necesitan cambiar los privilegios.
Como regla general, los shells implementan comandos como incorporados solo cuando esos comandos deben implementarse como incorporados. Los comandos como alias, cd, exit, export, jobs, ... necesidad de leer o modificar algún estado interno de la cáscara, y por lo tanto no puede ser programas independientes. Los comandos que no tienen tales requisitos pueden ser comandos separados; De esta manera, se pueden llamar desde cualquier shell u otro programa.
Mirando la lista de incorporados en bash, solo los siguientes incorporados podrían implementarse como comandos separados. Para algunos de ellos, habría una ligera pérdida de funcionalidad.
command- pero perdería su utilidad en situaciones en las que es PATHposible que no se configure correctamente y el script se esté utilizando commandcomo parte de la configuración.echo - Es una construcción para la eficiencia.help - podría usar una base de datos separada, pero incrustar el texto de ayuda en el ejecutable del shell tiene la ventaja de hacer que el ejecutable del shell sea autónomo.kill - Hay dos ventajas en tener un builtin incorporado: puede reconocer designaciones de trabajo además de las ID de proceso, y puede usarse incluso cuando no hay suficientes recursos para iniciar un proceso separado.printf- por la misma razón que echo, y también para admitir la -vopción de poner la salida en una variable.pwd - el incorporado ofrece la capacidad adicional de seguimiento lógico del directorio actual (dejando intactos los enlaces simbólicos en lugar de expandirlos).test- Es una función integrada para la eficiencia (y bash también hace algo de magia con archivos llamados /dev/fd/…en algunos sistemas operativos).Algunas conchas ofrecen un número significativo de incorporaciones adicionales. Hay faja , que es un shell diseñado para ser un binario independiente para reparaciones de emergencia (cuando algunos comandos externos pueden no ser utilizables). Tiene incorporado ls, llamado -ls, así como otras herramientas como -grepy -tar. Los componentes integrados de Sash tienen menos capacidades que los comandos completos. Zsh ofrece algunos componentes similares en su módulo zsh / files . No tiene ls, pero la expansión comodín ( echo *) y zstatpuede cumplir una función similar.
Creo que algo que falta a la gente aquí es la complejidad de corte del lsprograma GNU en Linux. Comparando el tamaño del ejecutable de lslabash y dashconchas en mi sistema Debian, vemos que es bastante grande:
graeme@graeme:~$ ls -lh /bin/{ls,bash,dash}
-rwxr-xr-x 1 root root 953K Mar 30 2013 /bin/bash
-rwxr-xr-x 1 root root 115K Dec 25 20:25 /bin/dash
-rwxr-xr-x 1 root root 108K Jul 20 22:52 /bin/ls
Incluyendo un ls versión tan completa como la versión GNU bashaumentaría el tamaño del ejecutable en un 10%. ¡Es casi del mismo tamaño que la dashcarcasa completa !
La mayoría de los componentes integrados de shell se eligen porque se integran con el shell de una manera que los ejecutables externos no pueden (la pregunta señala cd , pero otro ejemplo es la versión bash de killintegrarse con el control de trabajo bash) o porque son comandos muy simples de implementar, dando una gran recompensa de velocidad vs tamaño ( truey falseson casi tan simples como se pone).
GNU lsha tenido un largo ciclo de desarrollo e implementa muchas opciones para personalizar qué / cómo se muestran los resultados. El uso de un ls incorporado por defecto perdería esta funcionalidad o aumentaría significativamente la complejidad y el tamaño del shell.
Esto hace lo que buscas:
printf "%s\n" *
También puede almacenar nombres de archivo en una matriz:
files=(`printf "%s\n" *`) #items are separated by whitespace
echo ${#files[*]} files
for index in ${!a[*]}
do printf "%d: %s\n" $index ${a[$index]};
done
Pero no le importan los espacios en los nombres.
Esto pasa a variable y se preocupa por los espacios:
printf "%s\n" * | while read a; do echo $a; done
lses un programa externo,echo *oecho * .*(dependiendo de las opciones de shell) hace un trabajo bastante bueno de listar archivos sin bifurcación.